{"version":3,"sources":["webpack://App.[name]/./vendor/highcharts/exporting.js","webpack://App.[name]/./js/analytics.js","webpack://App.[name]/./vendor/highcharts/highcharts.src.js"],"names":["Highcharts","f","y","A","t","C","k","n","u","o","r","p","D","j","B","E","F","x","Chart","addEvent","removeEvent","createElement","discardElement","css","merge","each","extend","Math","max","document","window","isTouchDevice","Renderer","prototype","symbols","getOptions","lang","printChart","downloadPNG","downloadJPEG","downloadPDF","downloadSVG","contextButtonTitle","navigation","menuStyle","border","background","padding","menuItemStyle","color","fontSize","menuItemHoverStyle","buttonOptions","symbolFill","symbolSize","symbolStroke","symbolStrokeWidth","symbolX","symbolY","align","buttonSpacing","height","theme","fill","stroke","verticalAlign","width","exporting","type","url","buttons","contextButton","menuClassName","symbol","_titleKey","menuItems","textKey","onclick","this","print","separator","exportChart","post","c","a","d","b","method","action","enctype","display","body","name","value","submit","getSVG","z","h","g","options","createElementNS","position","top","chartWidth","chartHeight","renderTo","style","sourceWidth","chart","test","parseInt","sourceHeight","animation","forExport","enabled","series","showCheckbox","visible","isInternal","push","callback","getExtremes","userMin","userMax","setExtremes","container","innerHTML","destroy","replace","toLowerCase","borderRadius","chartOptions","filename","scale","svg","parentNode","childNodes","isPrinting","nodeType","appendChild","focus","setTimeout","contextMenu","v","w","e","q","l","m","i","s","className","zIndex","MozBoxShadow","WebkitBoxShadow","boxShadow","setState","openMenu","clearTimeout","pointer","inClass","target","onmouseover","onmouseout","apply","arguments","text","cursor","exportDivElements","exportMenuWidth","offsetWidth","exportMenuHeight","offsetHeight","right","left","alignOptions","bottom","addButton","renderer","btnCount","exportSVGElements","states","hover","select","translateX","translateY","paddingLeft","pick","button","attr","title","add","destroyExport","length","ontouchstart","menu","callbacks","props","email","$el","that","$","click","trackEvent","currentTarget","data","jQuery","root","factory","win","H","isNumber","map","pInt","doc","SVG_NS","userAgent","navigator","createSVGRect","isMS","opera","vml","isFirefox","hasBidiBug","split","error","product","version","deg2rad","PI","hasTouch","undefined","documentElement","isWebKit","chartCount","seriesTypes","symbolSizes","marginNames","noop","charts","uniqueKeyHash","idCounter","timers","code","stop","msg","Error","console","log","Fx","elem","prop","dSetter","startVal","start","paths","end","ret","now","toD","parseFloat","isNaN","update","step","element","unit","call","run","from","to","self","timer","gotoEnd","stopped","startTime","Date","pos","timerId","setInterval","splice","clearInterval","done","complete","duration","curAnim","objectEach","val","easing","initPath","fromD","shift","fullLength","slice","reverse","startX","endX","bezier","indexOf","numParams","isArea","positionFactor","sixify","arr","isOperator","nextIsOperator","insertSlice","subArr","index","concat","prepend","other","append","fillSetter","strokeSetter","tweenTo","len","args","doCopy","copy","original","key","isObject","isClass","isDOMElement","Array","mag","isString","isArray","obj","str","Object","toString","strict","constructor","erase","item","defined","setAttribute","getAttribute","splat","syncTimeout","fn","delay","context","arg","el","styles","opacity","filter","tag","attribs","parent","nopad","margin","extendClass","members","object","pad","number","padder","String","join","relativeLength","base","wrap","func","proceed","outerArgs","ctx","unshift","getTZOffset","timestamp","hcGetTimezoneOffset","hcTimezoneOffset","dateFormat","format","capitalize","defaultOptions","invalidDate","date","hours","hcGetHours","day","hcGetDay","dayOfMonth","hcGetDate","month","hcGetMonth","fullYear","hcGetFullYear","langWeekdays","weekdays","shortWeekdays","replacements","substr","shortMonths","months","hcGetMinutes","getSeconds","round","dateFormats","toUpperCase","formatSingle","decimals","match","numberFormat","decimalPoint","thousandsSep","segment","valueAndFormat","path","splitter","isInside","getMagnitude","num","pow","floor","LN10","normalizeTickInterval","interval","multiples","magnitude","allowDecimals","hasTickAmount","normalized","retInterval","grep","correctFloat","stableSort","sortFunction","sortValue","safeI","sort","arrayMin","min","arrayMax","destroyObjectProperties","except","garbageBin","prec","toPrecision","setAnimation","globalAnimation","animObject","timeUnits","millisecond","second","minute","hour","week","year","strinteger","thousands","roundedNumber","origDec","abs","toFixed","easeInOutSine","cos","getStyle","toInt","scrollWidth","scrollHeight","getComputedStyle","getPropertyValue","inArray","find","results","offset","docElem","box","getBoundingClientRect","pageYOffset","scrollTop","clientTop","pageXOffset","scrollLeft","clientLeft","forEach","hasOwnProperty","events","hcEvents","wrappedFn","srcElement","addEventListener","attachEvent","hcEventsIE","removeOneEvent","removeEventListener","detachEvent","removeAllEvents","types","nodeName","fireEvent","eventArguments","defaultFunction","createEvent","dispatchEvent","initEvent","preventDefault","defaultPrevented","animate","params","opt","fx","seriesType","pointProps","plotOptions","pointClass","Point","uniqueKey","random","substring","highcharts","defaultView","alias","zoom","currentStyle","elements","Color","input","init","parsers","regex","parse","result","names","none","white","black","rgba","parser","stops","exec","get","brighten","alpha","setOpacity","hasAlpha","SVGElement","SVGRenderer","textProps","animOptions","colorGradient","colorObject","gradName","gradAttr","radAttr","gradients","gradientObject","stopColor","stopOpacity","radialReference","id","radialGradient","linearGradient","x1","y1","x2","y2","gradientUnits","getRadialAttr","defs","stopObject","gradient","applyTextOutline","textOutline","tspans","tspan","strokeWidth","firstRealChild","getContrast","fakeTS","getElementsByTagName","ySetter","xSetter","digit","removeChild","firstChild","clone","cloneNode","insertBefore","hash","continueAnimation","hasSetSymbolSize","skipAttr","setter","_defaultGetter","symbolName","symbolAttr","rotation","doTransform","_defaultSetter","shadows","updateShadows","afterSetters","updateTransform","cutHeight","addClass","currentClassName","hasClass","removeClass","wrapper","clip","clipRect","crisp","rect","normalizer","textWidth","hyphenate","oldStyles","newStyles","serializedCss","hasNew","svgPseudoProps","added","buildText","on","eventType","handler","svgElement","touchEventFired","setRadialReference","coordinates","existingGradient","translate","invert","inverted","transform","scaleX","scaleY","toFront","alignByTranslate","vAlign","alignTo","alignFactor","vAlignFactor","alignedObjects","placed","alignAttr","getBBox","reload","rot","bBox","rad","toggleTextShadowShim","cacheKey","textStr","cache","cacheKeys","textOverflow","namespaceURI","querySelectorAll","htmlGetBBox","isSVG","sin","show","inherit","visibility","hide","fadeOut","elemWrapper","inserted","parentGroup","parentInverted","handleZ","zIndexSetter","onAdd","safeRemoveChild","grandParent","parentToClean","ownerSVGElement","onmousemove","point","clipPath","removeAttribute","destroyShadows","div","shadow","shadowOptions","group","cutOff","shadowWidth","shadowElementOpacity","offsetX","offsetY","xGetter","dashstyleSetter","alignSetter","center","opacitySetter","titleSetter","titleNode","createTextNode","textSetter","visibilitySetter","otherElement","otherZIndex","yGetter","translateXSetter","translateYSetter","rotationSetter","verticalAlignSetter","scaleXSetter","scaleYSetter","hasStroke","Element","allowHTML","boxWrapper","subPixelFix","location","href","imgCount","setSize","ceil","unSubPixelFix","fontFamily","setStyle","isHidden","rendererDefs","draw","cx","cy","getSpanWidth","actualWidth","measureSpanWidth","applyEllipsis","currentIndex","wasTooLong","minIndex","maxIndex","updateTSpan","lines","clsRegex","styleRegex","hrefRegex","textCache","isSubsequentLine","textNode","hasMarkup","parentX","textStyles","textLineHeight","lineHeight","ellipsis","noWrap","whiteSpace","tempParent","getLineHeight","fontSizeStyle","fontMetrics","unescapeAngleBrackets","inputStr","line","lineNo","spans","spanNo","span","spanCls","spanStyle","attributes","dx","tooLong","words","hasWhiteSpace","rest","dy","pop","normalState","hoverState","pressedState","disabledState","shape","normalStyle","hoverStyle","pressedStyle","disabledStyle","label","curState","fontWeight","state","crispLine","points","circle","arc","innerR","rSetter","rx","ry","viewBox","image","src","preserveAspectRatio","setAttributeNS","imageSrc","centerImage","ren","imageRegex","isImage","sym","symbolFn","imgwidth","imgheight","imgSize","trans","isImg","onload","chartIndex","open","innerRadius","cosStart","sinStart","cosEnd","sinEnd","longArc","callout","safeDistance","anchorX","anchorY","count","useHTML","fakeSVG","parentVal","html","rotCorr","baseline","alterY","wrapperX","wrapperY","textAlign","baselineOffset","getCrispAdjust","updateBoxSize","updateTextPadding","boxAttr","deferredAttr","hasBGImage","needsBox","crispAdjust","textY","textX","widthSetter","heightSetter","paddingSetter","paddingLeftSetter","anchorXSetter","anchorYSetter","baseCss","htmlCss","tagName","overflow","offsetLeft","offsetTop","htmlUpdateTransform","alignCorrection","marginLeft","marginTop","child","invertChild","currentTextTransform","cTT","setSpanRotation","textContent","innerText","getSpanCorrection","xCorr","yCorr","alignOnAdd","rotationStyle","cssTransformKey","transformOrigin","addSetters","svgGroupWrapper","htmlGroup","parents","htmlGroupStyle","cls","pointerEvents","VMLRenderer","VMLRendererExtension","VMLElement","docMode8","documentMode","markup","isDiv","prepVML","deferUpdateTransform","costheta","sintheta","quad","elemHeight","nonLeft","pathToVML","isArc","clipMembers","cssRet","destroyClip","getCSS","evt","event","cutOffPath","modifiedPath","elemStyle","cssText","setAttr","classSetter","filled","stroked","updateClipping","isIE8","isVML","namespaces","hcv","createStyleSheet","styleSheets","isObj","isShape","member","fillType","regexRgba","opacity1","opacity2","color1","color2","firstStop","lastStop","fillAttr","colors","addFillNode","atan","sizex","sizey","applyRadialGradient","global","VMLRadialGradientURL","propNodes","vmlStyle","coordsize","isCircle","parentStyle","imgStyle","flip","radius","measuringSpan","setTimeMethods","globalOptions","useUTC","GET","SET","timezoneOffset","moment","timezone","tz","utcOffset","getTimezoneOffset","getTimezoneOffsetOption","hcMakeTime","minutes","seconds","UTC","getTime","loading","numericSymbols","resetZoom","resetZoomTitle","defaultSeriesType","ignoreHiddenSeries","spacing","resetZoomButton","borderColor","backgroundColor","plotBorderColor","widthAdjust","subtitle","labels","legend","layout","labelFormatter","activeColor","inactiveColor","itemStyle","itemHoverStyle","itemHiddenStyle","itemCheckboxStyle","squareSymbol","symbolPadding","labelStyle","tooltip","dateTimeLabelFormats","footerFormat","snap","borderWidth","headerFormat","pointFormat","credits","setOptions","defaultPlotOptions","Tick","axis","noLabel","isNew","isNewLabel","addLabel","dateTimeLabelFormat","categories","labelOptions","tickPositions","isFirst","isLast","tickPositionInfo","info","isDatetimeAxis","higherRanks","unitName","isLog","lin2log","labelGroup","labelLength","getLabelSize","horiz","handleOverflow","xy","rightPos","pxPos","leftBound","labelLeft","rightBound","labelRight","factor","labelAlign","labelWidth","slotWidth","getSlotWidth","modifiedSlotWidth","xCorrection","goRight","autoRotation","getPosition","tickmarkOffset","old","cHeight","oldChartHeight","transB","opposite","oldChartWidth","getLabelPosition","transA","reversed","staggerLines","tickRotCorr","yOffset","side","labelOffset","getMarkPath","tickLength","tickWidth","renderGridLine","reverseCrisp","gridLinePath","gridLine","gridPrefix","gridLineWidth","gridLineColor","dashStyle","dashstyle","gridGroup","getPlotLinePath","renderMark","tickPrefix","tickSize","mark","isNewMark","isXAxis","tickColor","axisGroup","renderLabel","showFirstLabel","showLastLabel","isRadial","render","isActive","Axis","endOnTick","minPadding","maxPadding","minorTickLength","minorTickPosition","startOfWeek","startOnTick","tickmarkPlacement","tickPixelInterval","tickPosition","minorGridLineColor","minorGridLineWidth","minorTickColor","lineColor","lineWidth","defaultYAxisOptions","stackLabels","formatter","total","defaultLeftAxisOptions","defaultRightAxisOptions","defaultBottomAxisOptions","defaultTopAxisOptions","userOptions","isX","isZAxis","coll","defaultLabelFormatter","minPixelPadding","zoomEnabled","hasNames","plotLinesAndBandsGroups","positiveValuesOnly","allowNegativeLog","isLinked","linkedTo","ticks","labelEdge","minorTicks","plotLinesAndBands","alternateBands","minRange","userMinRange","maxZoom","range","stacks","oldStacks","stacksTouched","crosshair","crosshairs","axes","xAxis","linearToLogConverter","val2lin","log2lin","lin2val","multi","numSymMagnitude","numericSymbolMagnitude","formatOption","numericSymbolDetector","tickInterval","getSeriesExtremes","hasVisibleSeries","dataMin","dataMax","threshold","softThreshold","buildStacks","xData","seriesDataMin","seriesDataMax","seriesOptions","backwards","cvsCoord","handleLog","pointPlacement","returnValue","linkedParent","sign","cvsOffset","localA","oldTransA","localMin","oldMin","doPostTranslate","isOrdinal","isBroken","sector","toPixels","paneCoordinates","toValue","pixel","force","translatedValue","skip","axisLeft","axisTop","cWidth","between","getLinearTickPositions","lastPos","roundedMin","roundedMax","single","getMinorTickPositions","minorTickInterval","minorTickPositions","pointRangePadding","paddedTicks","getLogTickPositions","getTimeTicks","normalizeTimeTickInterval","trimTicks","adjustForMinRange","zoomOffset","spaceAvailable","closestDataRange","distance","loopLength","minArgs","maxArgs","xIncrement","getClosest","seriesClosest","closestPointRange","noSharedTooltip","nameToX","explicitCategories","nameX","requireSorting","uniqueNames","autoIncrement","updateNames","isDirtyData","processData","generatePoints","setAxisTranslation","saveOld","ordinalCorrection","pointRange","axisPointRange","minPointOffset","hasCategories","seriesPointRange","ordinalSlope","translationSlope","staticScale","minFromRange","setTickInterval","secondPass","linkedParentExtremes","minTickInterval","thresholdMin","thresholdMax","hardMin","hardMax","tickIntervalOption","tickPixelIntervalOption","getTickAmount","beforePadding","usePercentage","softMin","softMax","ceiling","tickAmount","oldMax","beforeSetTickPositions","postProcessTickInterval","unsquish","setTickPositions","tickPositionsOption","tickPositioner","units","ordinalPositions","adjustTickAmount","alignToOthers","hasOther","others","alignTicks","otherOptions","pane","finalTickAmt","currentTickAmount","setScale","isDirtyAxisLength","oldAxisLength","setAxisSize","isDirty","forceRedraw","oldUserMin","oldUserMax","resetStacks","cleanStacks","newMin","newMax","redraw","serie","kdTree","eventArgs","allowZoomOutside","displayBtn","trigger","offsets","plotWidth","plotHeight","plotTop","plotLeft","percentRegex","getThreshold","realMin","realMax","autoLabelAlign","angle","prefix","labelMetrics","newTickInterval","slotSize","rotationOption","bestScore","Number","MAX_VALUE","getStep","spaceNeeded","autoRotationLimit","score","labelRotation","slotCount","renderUnsquish","innerWidth","textOverflowOption","maxLabelLength","tick","specCss","hasData","addTitle","axisTitleOptions","axisTitle","low","middle","high","generateTick","getOffset","showAxis","titleOffsetOption","labelOffsetPadded","lineHeightCorrection","invertedSide","titleOffset","titleMargin","axisOffset","clipOffset","directionFactor","axisParent","showEmpty","gridZIndex","reserveSpace","1","3","renderLine","axisTitleMargin","axisLine","getLinePath","lineLeft","lineTop","getTitlePosition","axisLength","xOption","yOption","alongAxis","offAxis","renderMinorTick","slideInTicks","hasRendered","renderTick","stackLabelOptions","alternateGridColor","overlap","polar","PlotLineOrBand","_addedPlotLB","plotLines","plotBands","plotLineOptions","addPlotBandOrLine","forDestruction","isPlaced","titleXy","renderStackTotals","plotLine","keepProps","keepEvents","plotGroup","stack","stackKey","drawCrosshair","categorized","graphic","cross","plotX","plotY","chartX","chartY","stackY","hideCrosshair","normalizedInterval","minYear","variableDayLength","minDate","makeTime","unitRange","hcSetMilliseconds","getMilliseconds","hcSetSeconds","hcSetMinutes","hcSetHours","hcSetDate","hcSetMonth","hcSetFullYear","minMonth","minDateDate","minHours","time","totalRange","unitsOption","minor","positions","_minorAutoInterval","intermediate","break2","filteredTickIntervalOption","totalPixelLength","optionsLabel","isBand","isLine","svgElem","groupAttribs","groupName","getPlotBandPath","flat","xs","ys","toPath","plus","outside","addPlotBand","addPlotLine","removePlotBandOrLine","removePlotBand","removePlotLine","Tooltip","shared","cleanSplit","tt","getLabel","hideTimer","tooltipTimeout","move","skipAnchor","followPointer","hideDelay","getAnchor","mouseEvent","yAxis","tooltipPos","normalize","plotLow","plotHigh","boxWidth","boxHeight","swapped","first","preferFarSide","ttBelow","negative","firstDimension","dim","outerSize","innerSize","roomLeft","roomRight","alignedLeft","alignedRight","secondDimension","retVal","swap","temp","defaultFormatter","items","tooltipFooterHeaderFormatter","bodyFormatter","refresh","pointOrPoints","anchor","currentSeries","textConfig","pointConfig","tooltipOptions","getLabelConfig","category","renderSplit","spacingBox","colorIndex","updatePosition","headerHeight","boxes","rightAligned","tooltipLabel","isHeader","owner","colorClass","rank","size","distribute","positioner","getDateFormat","dateStr","blank","strpos","lastN","getXDateFormat","labelConfig","isFooter","footOrHead","xDateFormat","isDateTime","formatString","pointFormatter","tooltipFormatter","Pointer","runChartClick","pinchDown","lastValidTouch","followTouchMove","setDOMEvents","zoomOption","zoomX","zoomY","zoomType","pinchType","zoomHor","zoomVert","hasZoom","chartPosition","ePos","touches","changedTouches","pageX","clientX","pageY","getCoordinates","getKDPoints","directTouch","kdpointT","kdpoints","enableMouseTracking","searchPoint","findNearestPointBy","p1","p2","isCloserX","distX","isCloser","dist","isAbove","getPointFromEvent","getChartCoordinatesFromPoint","getHoverData","existingHoverPoint","existingHoverSeries","isDirectTouch","hoverPoint","hoverPoints","hoverSeries","searchSeries","useExisting","notSticky","stickyTracking","isHoverPoint","runPointActions","useSharedTooltip","hoverData","onMouseOver","firePointEvent","unDocMouseMove","hoverChartIndex","onDocumentMouseMove","reset","allowMove","tooltipPoints","isCartesian","onMouseOut","hoverX","scaleGroups","seriesAttribs","getPlotBox","markerGroup","dataLabelsGroup","clipBox","dragStart","mouseIsDown","cancelClick","mouseDownX","mouseDownY","drag","clickedInside","selectionMarker","panKey","touch","hasDragged","sqrt","isInsidePlot","hasCartesianSeries","selectionMarkerFill","panning","pan","drop","hasPinched","runZoom","selectionData","originalEvent","selectionBox","selectionLeft","selectionTop","selectionWidth","selectionHeight","selectionMin","selectionMax","_cursor","onContainerMouseDown","onDocumentMouseUp","onContainerMouseLeave","relatedTarget","toElement","onContainerMouseMove","elemClassName","onTrackerMouseOut","onContainerClick","onmousedown","onContainerTouchStart","ontouchmove","onContainerTouchMove","onDocumentTouchEnd","pinchTranslate","pinchTranslateDirection","forcedScale","selectionWH","selectionXY","clipXY","outOfBounds","transformScale","scaleKey","XY","sChartXY","wh","plotLeftTop","bounds","singleTouch","touch0Start","touch0Now","touch1Start","touch1Now","pinch","touchesLength","fireClickEvent","runTrackerClick","initiated","absMin","absMax","res","plotBox","hasMoved","PointerEvent","MSPointerEvent","hasPointerEvent","translateMSPointer","wktype","fake","pointerType","MSPOINTER_TYPE_TOUCH","onContainerPointerDown","pointerId","onContainerPointerMove","onDocumentPointerUp","batchMSEvents","Legend","positionCheckboxes","itemMarginTop","initialItemY","maxItemWidth","itemHeight","symbolWidth","pages","isDirtyLegend","isDirtyBox","colorizeItem","legendGroup","legendItem","legendLine","legendSymbol","hiddenColor","textColor","symbolColor","markerOptions","marker","isMarker","pointAttribs","positionItem","ltr","rtl","legendItemPos","_legendItemPos","itemX","itemY","checkbox","legendWidth","destroyItem","destroyItems","getAllItems","scrollOffset","clipHeight","legendHeight","titleHeight","allItems","checkboxOffset","renderTitle","titleOptions","contentGroup","setText","labelFormat","renderItem","itemWidth","horizontal","itemDistance","widthOption","itemMarginBottom","li","isSeries","drawLegendSymbol","createCheckboxForItem","itemExtraWidth","itemClassName","scrollGroup","symbolHeight","setItemEvents","legendItemWidth","legendItemHeight","lastLineHeight","lastItemY","showInLegend","legendItems","legendType","adjustMargins","alignment","charAt","floating","alignments","legendIndex","isResizing","lastY","optionsY","alignTop","spaceHeight","maxHeight","navOptions","arrowSize","nav","clipToHeight","currentPage","fullHeight","up","scroll","pager","down","scrollBy","pageCount","LegendSymbolMixin","drawRectangle","square","symbolRadius","drawLineMarker","generalRadius","legendItemGroup","verticalCenter","runPositionItem","getArgs","userPlotOptions","optionsChart","chartEvents","showAxes","pointCount","colorCounter","symbolCounter","firstRender","initSeries","Constr","orderSeries","fromIndex","hasStackedSeries","hasDirtyStacks","redrawLegend","isHiddenChart","afterRedraw","setResponsive","temporaryDisplay","layOutTitles","stacking","updateTotals","getStacks","getMargins","extKey","drawChartBox","itemById","getAxes","optionsArray","xAxisOptions","yAxisOptions","axisOptions","getSelectedPoints","selected","getSelectedSeries","setTitle","subtitleOptions","chartTitleOptions","chartSubtitleOptions","isStock","requiresDirtyBox","titleSize","getChartSize","heightOption","containerWidth","containerHeight","revert","tempStyle","node","hcOrigStyle","setProperty","setClassName","getContainer","oldChartIndex","Ren","containerStyle","containerId","getElementById","skipClone","skipAxes","resetMargins","extraMargin","extraTopMargin","getAxisMargins","setChartSize","reflow","hasUserWidth","reflowTimeout","initReflow","unbind","clipX","clipY","plotBorderWidth","clipOffsetSide","marginRight","marginBottom","plotSizeX","plotSizeY","values","sideName","chartBorderWidth","mgn","bgAttr","chartBackground","plotBackground","plotBorder","plotBGImage","chartBackgroundColor","plotBackgroundColor","plotBackgroundImage","verb","plotShadow","propFromSeries","klass","linkSeries","chartSeries","linkedSeries","renderSeries","renderLabels","tempWidth","tempHeight","redoHorizontal","redoVertical","seriesGroup","addCredits","mapCredits","scroller","isReadyToRender","readyState","serieOptions","colorCount","applyOptions","colorByPoint","pointValKey","optionsToObject","isNull","isValid","firstItemType","keys","pointArrayMap","valueCount","dataLabels","_hasPointLabels","_hasPointMarkers","getClassName","zone","getZone","zones","zoneAxis","dataLabel","destroyElements","percentage","stackTotal","seriesTooltipOptions","valueDecimals","valuePrefix","valueSuffix","importEvents","allowPointSelect","ctrlKey","metaKey","shiftKey","Series","radiusPlus","lineWidthPlus","fillColor","cropThreshold","halo","turboThreshold","sorted","axisTypes","parallelArrays","lastSeries","bindAxes","getColor","getSymbol","setData","_i","insert","collection","indexOption","AXIS","optionalAxis","updateParallelArrays","toYData","pointInterval","pointIntervalUnit","pointStart","itemOptions","typeOptions","negativeColor","negativeFillColor","getCyclic","defaults","setting","indexName","counterName","seriesMarkerOption","updatePoints","dataLength","pt","oldData","oldDataLength","firstPoint","yData","cropped","hasGroupedData","croppedData","xExtremes","processedXData","processedYData","cropStart","getExtremesFromAll","forceCrop","cropData","cropEnd","cropShoulder","dataOptions","PointClass","processedDataLength","dataGroup","groupMap","yDataLength","validValue","withinRange","activeYData","activeCounter","xMin","xMax","stackedYData","lastPlotX","stackIndicator","hasModifyValue","modifyValue","dynamicallyPlaced","stackThreshold","startFromThreshold","closestPointRangePx","pointStack","stackValues","xValue","yValue","yBottom","negStacks","getStackIndicator","setOffset","pointXOffset","barW","Infinity","getValidPoints","insideOnly","setClip","seriesClipBox","sharedClipKey","markerClipRect","afterAnimate","drawPoints","pointMarkerOptions","hasPointMarker","markerAttribs","seriesMarkerOptions","specialGroup","globallyEnabled","hasImage","seriesStateOptions","pointStateOptions","pointOptions","pointColorOption","pointColor","zoneColor","issue134","animationTimeout","survive","getGraphPath","nullsAsZeroes","connectCliffs","gap","graphPath","xMap","connectNulls","pathToPoint","lastPoint","leftCliff","rightCliff","getPointSpline","drawGraph","gappedPath","graphKey","graph","fillGraph","linecap","applyZones","translatedFrom","translatedTo","clipAttr","extremes","pxRange","pxPosMin","pxPosMax","clips","area","chartSizeMax","ignoreZones","invertGroups","remover","setInvert","animDuration","chartSeriesGroup","drawDataLabels","drawTracker","wasDirty","kdAxisArray","compareX","searchKDTree","buildKDTree","buildingKdTree","dimensions","_kdtree","depth","median","kdNow","kdX","kdY","kdComparer","kdDimensions","_search","search","tree","tdist","sideA","sideB","nPoint1","nPoint2","StackItem","isNegative","stackOption","xOffset","xWidth","neg","yZero","stackBox","crop","axisSeries","reversedStacks","setStackedPoints","setStackCliffs","setPercentStacks","stackTotalGroup","touched","cum","pointKey","negKey","singleStacks","pointExtremes","totalFactor","addSeries","addAxis","showLoading","loadingDiv","loadingOptions","setLoadingSize","loadingSpan","loadingShown","showDuration","hideLoading","hideDuration","propsRequireDirtyBox","propsRequireUpdateSeries","updateAllAxes","updateAllSeries","newWidth","newHeight","adders","newOptions","setSubtitle","runEvent","fixedBox","remove","removePoint","addPoint","isInTheMiddle","withEvent","oldOptions","oldType","newType","proto","preserve","setCategories","getStackPoints","visibleSeries","pointMap","seriesIndex","yAxisSeries","seriesLength","upOrDown","stackX","idx","stackPoint","stackedValues","direction","nullName","cliffName","cliff","otherStack","topPath","bottomPath","areaPath","bottomPoints","graphPoints","translatedThreshold","addDummyPoints","otherI","nullVal","cliffVal","isCliff","doCurve","rectPlotX","areaKey","fillOpacity","shiftUnit","leftContX","leftContY","rightContX","rightContY","nextPoint","otherPoint","lastX","nextX","nextY","correction","smoothing","areaProto","groupPadding","pointPadding","minPointLength","brightness","trackerGroups","otherSeries","getColumnMetrics","reversedXAxis","stackGroups","columnCount","grouping","columnIndex","otherYAxis","categoryWidth","pointOffsetWidth","pointWidth","maxPointWidth","columnMetrics","crispCol","fromTop","xCrisp","yCrisp","dense","metrics","seriesBarW","barX","barY","barH","shapeType","shapeArgs","stateOptions","p2o","pointAttrToOptions","strokeOption","strokeWidthOption","animationLimit","takeOrdinalPosition","CenteredSeriesMixin","getCenter","handleSlicingRoom","slicingRoom","slicedOffset","centerOption","smallestSize","ignoreHiddenPoint","column","startAngleRad","startR","finalConnectorOffset","radiusX","radiusY","cumulative","connectorOffset","startAngle","circ","endAngleRad","endAngle","labelDistance","getX","asin","maxLabelDistance","slicedTranslation","half","labelPos","groupTranslation","pointAttr","shadowGroup","getTranslate","sortByAngle","toggleSlice","setVisible","vis","sliced","haloPath","overlapping","origBoxes","restBoxes","sortByTarget","targets","posInCompositeBox","generalOptions","defer","dlProcessOptions","connector","dlOptions","contrastColor","inside","alignDataLabel","normRotation","negRotation","forceDL","justify","isLabelJustified","justifyDataLabel","off","justified","pie","dataLabelWidth","labelHeight","connectorPadding","connectorWidth","seriesCenter","centerY","halves","shortened","_pos","naturalY","sideOverflow","positionsIndex","positionIndex","_attr","verifyDataLabelOverflow","placeDataLabels","connectorColor","connectorPath","softConnector","moved","minSize","newSize","overshoot","dlBox","below","collectAndHide","collections","dataLabelCollections","allowOverlap","labelrank","hideOverlappingLabels","label1","label2","pos1","pos2","parent1","parent2","w1","h1","w2","h2","oldOpacity","newOpacity","isOld","TrackerMixin","drawTrackerPoint","_hasTracking","drawTrackerGraph","trackByArea","trackerPath","trackerPathLength","tracker","TRACKER_FILL","scatter","activeClass","fnLegendItemClick","browserEvent","checked","defaultChecked","showResetZoom","btnOptions","relativeTo","zoomOut","resetSelection","hasZoomed","displayButton","axisData","doRedraw","spill","mousePos","mouseDown","startPos","halfPointRange","panMin","panMax","flipped","paddedMin","paddedMax","accumulate","loopPoint","hasImportedEvents","haloOptions","newSymbol","normalDisabled","markerStateOptions","stateDisabled","stateMarkerGraphic","pointMarker","hasMarkers","currentSymbol","mouseOver","mouseOut","showOrHide","oldVisibility","currentRuleIds","responsive","ruleIds","currentResponsive","rules","rule","_id","matchResponsiveRule","mergedOptions","ruleId","undoOptions","currentOptions","matches","condition","maxWidth","minWidth","minHeight","getCurrent","curr","module","exports"],"mappings":"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","file":"1.chunk.js?v=eb01be89432f32fd2aae","sourcesContent":["/*\n Highcharts JS v3.0.7 (2013-10-24)\n Exporting module\n\n (c) 2010-2013 Torstein Hønsi\n\n License: www.highcharts.com/license\n*/\nrequire(['./highcharts.src.js'], function(Highcharts) {\n (function(f){var A=f.Chart,t=f.addEvent,C=f.removeEvent,k=f.createElement,n=f.discardElement,u=f.css,o=f.merge,r=f.each,p=f.extend,D=Math.max,j=document,B=window,E=f.isTouchDevice,F=f.Renderer.prototype.symbols,x=f.getOptions(),y;p(x.lang,{printChart:\"Print chart\",downloadPNG:\"Download PNG image\",downloadJPEG:\"Download JPEG image\",downloadPDF:\"Download PDF document\",downloadSVG:\"Download SVG vector image\",contextButtonTitle:\"Chart context menu\"});x.navigation={menuStyle:{border:\"1px solid #A0A0A0\",\n background:\"#FFFFFF\",padding:\"5px 0\"},menuItemStyle:{padding:\"0 10px\",background:\"none\",color:\"#303030\",fontSize:E?\"14px\":\"11px\"},menuItemHoverStyle:{background:\"#4572A5\",color:\"#FFFFFF\"},buttonOptions:{symbolFill:\"#E0E0E0\",symbolSize:14,symbolStroke:\"#666\",symbolStrokeWidth:3,symbolX:12.5,symbolY:10.5,align:\"right\",buttonSpacing:3,height:22,theme:{fill:\"white\",stroke:\"none\"},verticalAlign:\"top\",width:24}};x.exporting={type:\"image/png\",url:\"http://export.highcharts.com/\",buttons:{contextButton:{menuClassName:\"highcharts-contextmenu\",\n symbol:\"menu\",_titleKey:\"contextButtonTitle\",menuItems:[{textKey:\"printChart\",onclick:function(){this.print()}},{separator:!0},{textKey:\"downloadPNG\",onclick:function(){this.exportChart()}},{textKey:\"downloadJPEG\",onclick:function(){this.exportChart({type:\"image/jpeg\"})}},{textKey:\"downloadPDF\",onclick:function(){this.exportChart({type:\"application/pdf\"})}},{textKey:\"downloadSVG\",onclick:function(){this.exportChart({type:\"image/svg+xml\"})}}]}}};f.post=function(c,a){var d,b;b=k(\"form\",{method:\"post\",\n action:c,enctype:\"multipart/form-data\"},{display:\"none\"},j.body);for(d in a)k(\"input\",{type:\"hidden\",name:d,value:a[d]},null,b);b.submit();n(b)};p(A.prototype,{getSVG:function(c){var a=this,d,b,z,h,g=o(a.options,c);if(!j.createElementNS)j.createElementNS=function(a,b){return j.createElement(b)};c=k(\"div\",null,{position:\"absolute\",top:\"-9999em\",width:a.chartWidth+\"px\",height:a.chartHeight+\"px\"},j.body);b=a.renderTo.style.width;h=a.renderTo.style.height;b=g.exporting.sourceWidth||g.chart.width||/px$/.test(b)&&\n parseInt(b,10)||600;h=g.exporting.sourceHeight||g.chart.height||/px$/.test(h)&&parseInt(h,10)||400;p(g.chart,{animation:!1,renderTo:c,forExport:!0,width:b,height:h});g.exporting.enabled=!1;g.series=[];r(a.series,function(a){z=o(a.options,{animation:!1,showCheckbox:!1,visible:a.visible});z.isInternal||g.series.push(z)});d=new f.Chart(g,a.callback);r([\"xAxis\",\"yAxis\"],function(b){r(a[b],function(a,c){var g=d[b][c],f=a.getExtremes(),h=f.userMin,f=f.userMax;g&&(h!==void 0||f!==void 0)&&g.setExtremes(h,\n f,!0,!1)})});b=d.container.innerHTML;g=null;d.destroy();n(c);b=b.replace(/zIndex=\"[^\"]+\"/g,\"\").replace(/isShadow=\"[^\"]+\"/g,\"\").replace(/symbolName=\"[^\"]+\"/g,\"\").replace(/jQuery[0-9]+=\"[^\"]+\"/g,\"\").replace(/url\\([^#]+#/g,\"url(#\").replace(/.*?$/,\"\").replace(/ /g,\" \").replace(/­/g,\"­\").replace(//g,'xlink:href=\"$1\"/>').replace(/id=([^\" >]+)/g,'id=\"$1\"').replace(/class=([^\" >]+)/g,'class=\"$1\"').replace(/ transform /g,\" \").replace(/:(path|rect)/g,\"$1\").replace(/style=\"([^\"]+)\"/g,function(a){return a.toLowerCase()});return b=b.replace(/(url\\(#highcharts-[0-9]+)"/g,\"$1\").replace(/"/g,\"'\")},exportChart:function(c,a){var c=c||{},d=this.options.exporting,d=this.getSVG(o({chart:{borderRadius:0}},d.chartOptions,a,{exporting:{sourceWidth:c.sourceWidth||\n d.sourceWidth,sourceHeight:c.sourceHeight||d.sourceHeight}})),c=o(this.options.exporting,c);f.post(c.url,{filename:c.filename||\"chart\",type:c.type,width:c.width||0,scale:c.scale||2,svg:d})},print:function(){var c=this,a=c.container,d=[],b=a.parentNode,f=j.body,h=f.childNodes;if(!c.isPrinting)c.isPrinting=!0,r(h,function(a,b){if(a.nodeType===1)d[b]=a.style.display,a.style.display=\"none\"}),f.appendChild(a),B.focus(),B.print(),setTimeout(function(){b.appendChild(a);r(h,function(a,b){if(a.nodeType===\n 1)a.style.display=d[b]});c.isPrinting=!1},1E3)},contextMenu:function(c,a,d,b,f,h,g){var e=this,j=e.options.navigation,q=j.menuItemStyle,l=e.chartWidth,m=e.chartHeight,o=\"cache-\"+c,i=e[o],s=D(f,h),v,w,n;if(!i)e[o]=i=k(\"div\",{className:c},{position:\"absolute\",zIndex:1E3,padding:s+\"px\"},e.container),v=k(\"div\",null,p({MozBoxShadow:\"3px 3px 10px #888\",WebkitBoxShadow:\"3px 3px 10px #888\",boxShadow:\"3px 3px 10px #888\"},j.menuStyle),i),w=function(){u(i,{display:\"none\"});g&&g.setState(0);e.openMenu=!1},t(i,\n \"mouseleave\",function(){n=setTimeout(w,500)}),t(i,\"mouseenter\",function(){clearTimeout(n)}),t(document,\"mouseup\",function(a){e.pointer.inClass(a.target,c)||w()}),r(a,function(a){if(a){var b=a.separator?k(\"hr\",null,null,v):k(\"div\",{onmouseover:function(){u(this,j.menuItemHoverStyle)},onmouseout:function(){u(this,q)},onclick:function(){w();a.onclick.apply(e,arguments)},innerHTML:a.text||e.options.lang[a.textKey]},p({cursor:\"pointer\"},q),v);e.exportDivElements.push(b)}}),e.exportDivElements.push(v,i),\n e.exportMenuWidth=i.offsetWidth,e.exportMenuHeight=i.offsetHeight;a={display:\"block\"};d+e.exportMenuWidth>l?a.right=l-d-f-s+\"px\":a.left=d-s+\"px\";b+h+e.exportMenuHeight>m&&g.alignOptions.verticalAlign!==\"top\"?a.bottom=m-b-s+\"px\":a.top=b+h-s+\"px\";u(i,a);e.openMenu=!0},addButton:function(c){var a=this,d=a.renderer,b=o(a.options.navigation.buttonOptions,c),j=b.onclick,h=b.menuItems,g,e,k={stroke:b.symbolStroke,fill:b.symbolFill},q=b.symbolSize||12;if(!a.btnCount)a.btnCount=0;if(!a.exportDivElements)a.exportDivElements=\n [],a.exportSVGElements=[];if(b.enabled!==!1){var l=b.theme,m=l.states,n=m&&m.hover,m=m&&m.select,i;delete l.states;j?i=function(){j.apply(a,arguments)}:h&&(i=function(){a.contextMenu(e.menuClassName,h,e.translateX,e.translateY,e.width,e.height,e);e.setState(2)});b.text&&b.symbol?l.paddingLeft=f.pick(l.paddingLeft,25):b.text||p(l,{width:b.width,height:b.height,padding:0});e=d.button(b.text,0,0,i,l,n,m).attr({title:a.options.lang[b._titleKey],\"stroke-linecap\":\"round\"});e.menuClassName=c.menuClassName||\n \"highcharts-menu-\"+a.btnCount++;b.symbol&&(g=d.symbol(b.symbol,b.symbolX-q/2,b.symbolY-q/2,q,q).attr(p(k,{\"stroke-width\":b.symbolStrokeWidth||1,zIndex:1})).add(e));e.add().align(p(b,{width:e.width,x:f.pick(b.x,y)}),!0,\"spacingBox\");y+=(e.width+b.buttonSpacing)*(b.align===\"right\"?-1:1);a.exportSVGElements.push(e,g)}},destroyExport:function(c){var c=c.target,a,d;for(a=0;a}\n * @memberOf Highcharts\n */\n charts: []\n };\n return Highcharts;\n }());\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n /* eslint max-len: [\"warn\", 80, 4] */\n\n /**\n * The Highcharts object is the placeholder for all other members, and various\n * utility functions. The most important member of the namespace would be the\n * chart constructor.\n *\n * @example\n * var chart = Highcharts.chart('container', { ... });\n * \n * @namespace Highcharts\n */\n\n var timers = [];\n\n var charts = H.charts,\n doc = H.doc,\n win = H.win;\n\n /**\n * Provide error messages for debugging, with links to online explanation. This\n * function can be overridden to provide custom error handling.\n *\n * @function #error\n * @memberOf Highcharts\n * @param {Number|String} code - The error code. See [errors.xml]{@link \n * https://github.com/highcharts/highcharts/blob/master/errors/errors.xml}\n * for available codes. If it is a string, the error message is printed\n * directly in the console.\n * @param {Boolean} [stop=false] - Whether to throw an error or just log a \n * warning in the console.\n *\n * @sample highcharts/chart/highcharts-error/ Custom error handler\n */\n H.error = function(code, stop) {\n var msg = H.isNumber(code) ?\n 'Highcharts error #' + code + ': www.highcharts.com/errors/' + code :\n code;\n if (stop) {\n throw new Error(msg);\n }\n // else ...\n if (win.console) {\n console.log(msg); // eslint-disable-line no-console\n }\n };\n\n /**\n * An animator object used internally. One instance applies to one property\n * (attribute or style prop) on one element. Animation is always initiated\n * through {@link SVGElement#animate}.\n *\n * @constructor Fx\n * @memberOf Highcharts\n * @param {HTMLDOMElement|SVGElement} elem - The element to animate.\n * @param {AnimationOptions} options - Animation options.\n * @param {string} prop - The single attribute or CSS property to animate.\n * @private\n *\n * @example\n * var rect = renderer.rect(0, 0, 10, 10).add();\n * rect.animate({ width: 100 });\n */\n H.Fx = function(elem, options, prop) {\n this.options = options;\n this.elem = elem;\n this.prop = prop;\n };\n H.Fx.prototype = {\n\n /**\n * Set the current step of a path definition on SVGElement.\n *\n * @function #dSetter\n * @memberOf Highcharts.Fx\n */\n dSetter: function() {\n var start = this.paths[0],\n end = this.paths[1],\n ret = [],\n now = this.now,\n i = start.length,\n startVal;\n\n // Land on the final path without adjustment points appended in the ends\n if (now === 1) {\n ret = this.toD;\n\n } else if (i === end.length && now < 1) {\n while (i--) {\n startVal = parseFloat(start[i]);\n ret[i] =\n isNaN(startVal) ? // a letter instruction like M or L\n start[i] :\n now * (parseFloat(end[i] - startVal)) + startVal;\n\n }\n // If animation is finished or length not matching, land on right value\n } else {\n ret = end;\n }\n this.elem.attr('d', ret, null, true);\n },\n\n /**\n * Update the element with the current animation step.\n *\n * @function #update\n * @memberOf Highcharts.Fx\n */\n update: function() {\n var elem = this.elem,\n prop = this.prop, // if destroyed, it is null\n now = this.now,\n step = this.options.step;\n\n // Animation setter defined from outside\n if (this[prop + 'Setter']) {\n this[prop + 'Setter']();\n\n // Other animations on SVGElement\n } else if (elem.attr) {\n if (elem.element) {\n elem.attr(prop, now, null, true);\n }\n\n // HTML styles, raw HTML content like container size\n } else {\n elem.style[prop] = now + this.unit;\n }\n\n if (step) {\n step.call(elem, now, this);\n }\n\n },\n\n /**\n * Run an animation.\n *\n * @function #run\n * @memberOf Highcharts.Fx\n * @param {Number} from - The current value, value to start from.\n * @param {Number} to - The end value, value to land on.\n * @param {String} [unit] - The property unit, for example `px`.\n * @returns {void}\n */\n run: function(from, to, unit) {\n var self = this,\n timer = function(gotoEnd) {\n return timer.stopped ? false : self.step(gotoEnd);\n },\n i;\n\n this.startTime = +new Date();\n this.start = from;\n this.end = to;\n this.unit = unit;\n this.now = this.start;\n this.pos = 0;\n\n timer.elem = this.elem;\n timer.prop = this.prop;\n\n if (timer() && timers.push(timer) === 1) {\n timer.timerId = setInterval(function() {\n\n for (i = 0; i < timers.length; i++) {\n if (!timers[i]()) {\n timers.splice(i--, 1);\n }\n }\n\n if (!timers.length) {\n clearInterval(timer.timerId);\n }\n }, 13);\n }\n },\n\n /**\n * Run a single step in the animation.\n *\n * @function #step\n * @memberOf Highcharts.Fx\n * @param {Boolean} [gotoEnd] - Whether to go to the endpoint of the\n * animation after abort.\n * @returns {Boolean} Returns `true` if animation continues.\n */\n step: function(gotoEnd) {\n var t = +new Date(),\n ret,\n done,\n options = this.options,\n elem = this.elem,\n complete = options.complete,\n duration = options.duration,\n curAnim = options.curAnim;\n\n if (elem.attr && !elem.element) { // #2616, element is destroyed\n ret = false;\n\n } else if (gotoEnd || t >= duration + this.startTime) {\n this.now = this.end;\n this.pos = 1;\n this.update();\n\n curAnim[this.prop] = true;\n\n done = true;\n\n H.objectEach(curAnim, function(val) {\n if (val !== true) {\n done = false;\n }\n });\n\n if (done && complete) {\n complete.call(elem);\n }\n ret = false;\n\n } else {\n this.pos = options.easing((t - this.startTime) / duration);\n this.now = this.start + ((this.end - this.start) * this.pos);\n this.update();\n ret = true;\n }\n return ret;\n },\n\n /**\n * Prepare start and end values so that the path can be animated one to one.\n *\n * @function #initPath\n * @memberOf Highcharts.Fx\n * @param {SVGElement} elem - The SVGElement item.\n * @param {String} fromD - Starting path definition.\n * @param {Array} toD - Ending path definition.\n * @returns {Array} An array containing start and end paths in array form\n * so that they can be animated in parallel.\n */\n initPath: function(elem, fromD, toD) {\n fromD = fromD || '';\n var shift,\n startX = elem.startX,\n endX = elem.endX,\n bezier = fromD.indexOf('C') > -1,\n numParams = bezier ? 7 : 3,\n fullLength,\n slice,\n i,\n start = fromD.split(' '),\n end = toD.slice(), // copy\n isArea = elem.isArea,\n positionFactor = isArea ? 2 : 1,\n reverse;\n\n /**\n * In splines make moveTo and lineTo points have six parameters like\n * bezier curves, to allow animation one-to-one.\n */\n function sixify(arr) {\n var isOperator,\n nextIsOperator;\n i = arr.length;\n while (i--) {\n\n // Fill in dummy coordinates only if the next operator comes\n // three places behind (#5788)\n isOperator = arr[i] === 'M' || arr[i] === 'L';\n nextIsOperator = /[a-zA-Z]/.test(arr[i + 3]);\n if (isOperator && nextIsOperator) {\n arr.splice(\n i + 1, 0,\n arr[i + 1], arr[i + 2],\n arr[i + 1], arr[i + 2]\n );\n }\n }\n }\n\n /**\n * Insert an array at the given position of another array\n */\n function insertSlice(arr, subArr, index) {\n [].splice.apply(\n arr, [index, 0].concat(subArr)\n );\n }\n\n /**\n * If shifting points, prepend a dummy point to the end path. \n */\n function prepend(arr, other) {\n while (arr.length < fullLength) {\n\n // Move to, line to or curve to?\n arr[0] = other[fullLength - arr.length];\n\n // Prepend a copy of the first point\n insertSlice(arr, arr.slice(0, numParams), 0);\n\n // For areas, the bottom path goes back again to the left, so we\n // need to append a copy of the last point.\n if (isArea) {\n insertSlice(\n arr,\n arr.slice(arr.length - numParams), arr.length\n );\n i--;\n }\n }\n arr[0] = 'M';\n }\n\n /**\n * Copy and append last point until the length matches the end length\n */\n function append(arr, other) {\n var i = (fullLength - arr.length) / numParams;\n while (i > 0 && i--) {\n\n // Pull out the slice that is going to be appended or inserted.\n // In a line graph, the positionFactor is 1, and the last point\n // is sliced out. In an area graph, the positionFactor is 2,\n // causing the middle two points to be sliced out, since an area\n // path starts at left, follows the upper path then turns and\n // follows the bottom back. \n slice = arr.slice().splice(\n (arr.length / positionFactor) - numParams,\n numParams * positionFactor\n );\n\n // Move to, line to or curve to?\n slice[0] = other[fullLength - numParams - (i * numParams)];\n\n // Disable first control point\n if (bezier) {\n slice[numParams - 6] = slice[numParams - 2];\n slice[numParams - 5] = slice[numParams - 1];\n }\n\n // Now insert the slice, either in the middle (for areas) or at\n // the end (for lines)\n insertSlice(arr, slice, arr.length / positionFactor);\n\n if (isArea) {\n i--;\n }\n }\n }\n\n if (bezier) {\n sixify(start);\n sixify(end);\n }\n\n // For sideways animation, find out how much we need to shift to get the\n // start path Xs to match the end path Xs.\n if (startX && endX) {\n for (i = 0; i < startX.length; i++) {\n // Moving left, new points coming in on right\n if (startX[i] === endX[0]) {\n shift = i;\n break;\n // Moving right\n } else if (startX[0] ===\n endX[endX.length - startX.length + i]) {\n shift = i;\n reverse = true;\n break;\n }\n }\n if (shift === undefined) {\n start = [];\n }\n }\n\n if (start.length && H.isNumber(shift)) {\n\n // The common target length for the start and end array, where both \n // arrays are padded in opposite ends\n fullLength = end.length + shift * positionFactor * numParams;\n\n if (!reverse) {\n prepend(end, start);\n append(start, end);\n } else {\n prepend(start, end);\n append(end, start);\n }\n }\n\n return [start, end];\n }\n }; // End of Fx prototype\n\n /**\n * Handle animation of the color attributes directly.\n */\n H.Fx.prototype.fillSetter =\n H.Fx.prototype.strokeSetter = function() {\n this.elem.attr(\n this.prop,\n H.color(this.start).tweenTo(H.color(this.end), this.pos),\n null,\n true\n );\n };\n\n\n /**\n * Utility function to extend an object with the members of another.\n *\n * @function #extend\n * @memberOf Highcharts\n * @param {Object} a - The object to be extended.\n * @param {Object} b - The object to add to the first one.\n * @returns {Object} Object a, the original object.\n */\n H.extend = function(a, b) {\n var n;\n if (!a) {\n a = {};\n }\n for (n in b) {\n a[n] = b[n];\n }\n return a;\n };\n\n /**\n * Utility function to deep merge two or more objects and return a third object.\n * If the first argument is true, the contents of the second object is copied\n * into the first object. The merge function can also be used with a single \n * object argument to create a deep copy of an object.\n *\n * @function #merge\n * @memberOf Highcharts\n * @param {Boolean} [extend] - Whether to extend the left-side object (a) or\n return a whole new object.\n * @param {Object} a - The first object to extend. When only this is given, the\n function returns a deep copy.\n * @param {...Object} [n] - An object to merge into the previous one.\n * @returns {Object} - The merged object. If the first argument is true, the \n * return is the same as the second argument.\n */\n H.merge = function() {\n var i,\n args = arguments,\n len,\n ret = {},\n doCopy = function(copy, original) {\n // An object is replacing a primitive\n if (typeof copy !== 'object') {\n copy = {};\n }\n\n H.objectEach(original, function(value, key) {\n\n // Copy the contents of objects, but not arrays or DOM nodes\n if (\n H.isObject(value, true) &&\n !H.isClass(value) &&\n !H.isDOMElement(value)\n ) {\n copy[key] = doCopy(copy[key] || {}, value);\n\n // Primitives and arrays are copied over directly\n } else {\n copy[key] = original[key];\n }\n });\n return copy;\n };\n\n // If first argument is true, copy into the existing object. Used in\n // setOptions.\n if (args[0] === true) {\n ret = args[1];\n args = Array.prototype.slice.call(args, 2);\n }\n\n // For each argument, extend the return\n len = args.length;\n for (i = 0; i < len; i++) {\n ret = doCopy(ret, args[i]);\n }\n\n return ret;\n };\n\n /**\n * Shortcut for parseInt\n * @ignore\n * @param {Object} s\n * @param {Number} mag Magnitude\n */\n H.pInt = function(s, mag) {\n return parseInt(s, mag || 10);\n };\n\n /**\n * Utility function to check for string type.\n *\n * @function #isString\n * @memberOf Highcharts\n * @param {Object} s - The item to check.\n * @returns {Boolean} - True if the argument is a string.\n */\n H.isString = function(s) {\n return typeof s === 'string';\n };\n\n /**\n * Utility function to check if an item is an array.\n *\n * @function #isArray\n * @memberOf Highcharts\n * @param {Object} obj - The item to check.\n * @returns {Boolean} - True if the argument is an array.\n */\n H.isArray = function(obj) {\n var str = Object.prototype.toString.call(obj);\n return str === '[object Array]' || str === '[object Array Iterator]';\n };\n\n /**\n * Utility function to check if an item is of type object.\n *\n * @function #isObject\n * @memberOf Highcharts\n * @param {Object} obj - The item to check.\n * @param {Boolean} [strict=false] - Also checks that the object is not an\n * array.\n * @returns {Boolean} - True if the argument is an object.\n */\n H.isObject = function(obj, strict) {\n return !!obj && typeof obj === 'object' && (!strict || !H.isArray(obj));\n };\n\n /**\n * Utility function to check if an Object is a HTML Element.\n *\n * @function #isDOMElement\n * @memberOf Highcharts\n * @param {Object} obj - The item to check.\n * @returns {Boolean} - True if the argument is a HTML Element.\n */\n H.isDOMElement = function(obj) {\n return H.isObject(obj) && typeof obj.nodeType === 'number';\n };\n\n /**\n * Utility function to check if an Object is an class.\n *\n * @function #isClass\n * @memberOf Highcharts\n * @param {Object} obj - The item to check.\n * @returns {Boolean} - True if the argument is an class.\n */\n H.isClass = function(obj) {\n var c = obj && obj.constructor;\n return !!(\n H.isObject(obj, true) &&\n !H.isDOMElement(obj) &&\n (c && c.name && c.name !== 'Object')\n );\n };\n\n /**\n * Utility function to check if an item is of type number.\n *\n * @function #isNumber\n * @memberOf Highcharts\n * @param {Object} n - The item to check.\n * @returns {Boolean} - True if the item is a number and is not NaN.\n */\n H.isNumber = function(n) {\n return typeof n === 'number' && !isNaN(n);\n };\n\n /**\n * Remove the last occurence of an item from an array.\n *\n * @function #erase\n * @memberOf Highcharts\n * @param {Array} arr - The array.\n * @param {*} item - The item to remove.\n */\n H.erase = function(arr, item) {\n var i = arr.length;\n while (i--) {\n if (arr[i] === item) {\n arr.splice(i, 1);\n break;\n }\n }\n };\n\n /**\n * Check if an object is null or undefined.\n *\n * @function #defined\n * @memberOf Highcharts\n * @param {Object} obj - The object to check.\n * @returns {Boolean} - False if the object is null or undefined, otherwise\n * true.\n */\n H.defined = function(obj) {\n return obj !== undefined && obj !== null;\n };\n\n /**\n * Set or get an attribute or an object of attributes. To use as a setter, pass\n * a key and a value, or let the second argument be a collection of keys and\n * values. To use as a getter, pass only a string as the second argument.\n *\n * @function #attr\n * @memberOf Highcharts\n * @param {Object} elem - The DOM element to receive the attribute(s).\n * @param {String|Object} [prop] - The property or an object of key-value pairs.\n * @param {String} [value] - The value if a single property is set.\n * @returns {*} When used as a getter, return the value.\n */\n H.attr = function(elem, prop, value) {\n var ret;\n\n // if the prop is a string\n if (H.isString(prop)) {\n // set the value\n if (H.defined(value)) {\n elem.setAttribute(prop, value);\n\n // get the value\n } else if (elem && elem.getAttribute) {\n ret = elem.getAttribute(prop);\n }\n\n // else if prop is defined, it is a hash of key/value pairs\n } else if (H.defined(prop) && H.isObject(prop)) {\n H.objectEach(prop, function(val, key) {\n elem.setAttribute(key, val);\n });\n }\n return ret;\n };\n\n /**\n * Check if an element is an array, and if not, make it into an array.\n *\n * @function #splat\n * @memberOf Highcharts\n * @param obj {*} - The object to splat.\n * @returns {Array} The produced or original array.\n */\n H.splat = function(obj) {\n return H.isArray(obj) ? obj : [obj];\n };\n\n /**\n * Set a timeout if the delay is given, otherwise perform the function\n * synchronously.\n *\n * @function #syncTimeout\n * @memberOf Highcharts\n * @param {Function} fn - The function callback.\n * @param {Number} delay - Delay in milliseconds.\n * @param {Object} [context] - The context.\n * @returns {Number} An identifier for the timeout that can later be cleared\n * with clearTimeout.\n */\n H.syncTimeout = function(fn, delay, context) {\n if (delay) {\n return setTimeout(fn, delay, context);\n }\n fn.call(0, context);\n };\n\n\n /**\n * Return the first value that is not null or undefined.\n *\n * @function #pick\n * @memberOf Highcharts\n * @param {...*} items - Variable number of arguments to inspect.\n * @returns {*} The value of the first argument that is not null or undefined.\n */\n H.pick = function() {\n var args = arguments,\n i,\n arg,\n length = args.length;\n for (i = 0; i < length; i++) {\n arg = args[i];\n if (arg !== undefined && arg !== null) {\n return arg;\n }\n }\n };\n\n /**\n * @typedef {Object} CSSObject - A style object with camel case property names.\n * The properties can be whatever styles are supported on the given SVG or HTML\n * element.\n * @example\n * {\n * fontFamily: 'monospace',\n * fontSize: '1.2em'\n * }\n */\n /**\n * Set CSS on a given element.\n *\n * @function #css\n * @memberOf Highcharts\n * @param {HTMLDOMElement} el - A HTML DOM element.\n * @param {CSSObject} styles - Style object with camel case property names.\n * @returns {void}\n */\n H.css = function(el, styles) {\n if (H.isMS && !H.svg) { // #2686\n if (styles && styles.opacity !== undefined) {\n styles.filter = 'alpha(opacity=' + (styles.opacity * 100) + ')';\n }\n }\n H.extend(el.style, styles);\n };\n\n /**\n * A HTML DOM element.\n * @typedef {Object} HTMLDOMElement\n */\n\n /**\n * Utility function to create an HTML element with attributes and styles.\n *\n * @function #createElement\n * @memberOf Highcharts\n * @param {String} tag - The HTML tag.\n * @param {Object} [attribs] - Attributes as an object of key-value pairs.\n * @param {CSSObject} [styles] - Styles as an object of key-value pairs.\n * @param {Object} [parent] - The parent HTML object.\n * @param {Boolean} [nopad=false] - If true, remove all padding, border and\n * margin.\n * @returns {HTMLDOMElement} The created DOM element.\n */\n H.createElement = function(tag, attribs, styles, parent, nopad) {\n var el = doc.createElement(tag),\n css = H.css;\n if (attribs) {\n H.extend(el, attribs);\n }\n if (nopad) {\n css(el, {\n padding: 0,\n border: 'none',\n margin: 0\n });\n }\n if (styles) {\n css(el, styles);\n }\n if (parent) {\n parent.appendChild(el);\n }\n return el;\n };\n\n /**\n * Extend a prototyped class by new members.\n *\n * @function #extendClass\n * @memberOf Highcharts\n * @param {Object} parent - The parent prototype to inherit.\n * @param {Object} members - A collection of prototype members to add or\n * override compared to the parent prototype.\n * @returns {Object} A new prototype.\n */\n H.extendClass = function(parent, members) {\n var object = function() {};\n object.prototype = new parent(); // eslint-disable-line new-cap\n H.extend(object.prototype, members);\n return object;\n };\n\n /**\n * Left-pad a string to a given length by adding a character repetetively.\n *\n * @function #pad\n * @memberOf Highcharts\n * @param {Number} number - The input string or number.\n * @param {Number} length - The desired string length.\n * @param {String} [padder=0] - The character to pad with.\n * @returns {String} The padded string.\n */\n H.pad = function(number, length, padder) {\n return new Array((length || 2) + 1 -\n String(number).length).join(padder || 0) + number;\n };\n\n /**\n * @typedef {Number|String} RelativeSize - If a number is given, it defines the\n * pixel length. If a percentage string is given, like for example `'50%'`,\n * the setting defines a length relative to a base size, for example the size\n * of a container.\n */\n /**\n * Return a length based on either the integer value, or a percentage of a base.\n *\n * @function #relativeLength\n * @memberOf Highcharts\n * @param {RelativeSize} value - A percentage string or a number.\n * @param {Number} base - The full length that represents 100%.\n * @returns {Number} The computed length.\n */\n H.relativeLength = function(value, base) {\n return (/%$/).test(value) ?\n base * parseFloat(value) / 100 :\n parseFloat(value);\n };\n\n /**\n * Wrap a method with extended functionality, preserving the original function.\n *\n * @function #wrap\n * @memberOf Highcharts\n * @param {Object} obj - The context object that the method belongs to. In real\n * cases, this is often a prototype.\n * @param {String} method - The name of the method to extend.\n * @param {Function} func - A wrapper function callback. This function is called\n * with the same arguments as the original function, except that the\n * original function is unshifted and passed as the first argument.\n * @returns {void}\n */\n H.wrap = function(obj, method, func) {\n var proceed = obj[method];\n obj[method] = function() {\n var args = Array.prototype.slice.call(arguments),\n outerArgs = arguments,\n ctx = this,\n ret;\n ctx.proceed = function() {\n proceed.apply(ctx, arguments.length ? arguments : outerArgs);\n };\n args.unshift(proceed);\n ret = func.apply(this, args);\n ctx.proceed = null;\n return ret;\n };\n };\n\n /**\n * Get the time zone offset based on the current timezone information as set in\n * the global options.\n *\n * @function #getTZOffset\n * @memberOf Highcharts\n * @param {Number} timestamp - The JavaScript timestamp to inspect.\n * @return {Number} - The timezone offset in minutes compared to UTC.\n */\n H.getTZOffset = function(timestamp) {\n var d = H.Date;\n return ((d.hcGetTimezoneOffset && d.hcGetTimezoneOffset(timestamp)) ||\n d.hcTimezoneOffset || 0) * 60000;\n };\n\n /**\n * Formats a JavaScript date timestamp (milliseconds since Jan 1st 1970) into a\n * human readable date string. The format is a subset of the formats for PHP's\n * [strftime]{@link\n * http://www.php.net/manual/en/function.strftime.php} function. Additional\n * formats can be given in the {@link Highcharts.dateFormats} hook.\n *\n * @function #dateFormat\n * @memberOf Highcharts\n * @param {String} format - The desired format where various time\n * representations are prefixed with %.\n * @param {Number} timestamp - The JavaScript timestamp.\n * @param {Boolean} [capitalize=false] - Upper case first letter in the return.\n * @returns {String} The formatted date.\n */\n H.dateFormat = function(format, timestamp, capitalize) {\n if (!H.defined(timestamp) || isNaN(timestamp)) {\n return H.defaultOptions.lang.invalidDate || '';\n }\n format = H.pick(format, '%Y-%m-%d %H:%M:%S');\n\n var D = H.Date,\n date = new D(timestamp - H.getTZOffset(timestamp)),\n // get the basic time values\n hours = date[D.hcGetHours](),\n day = date[D.hcGetDay](),\n dayOfMonth = date[D.hcGetDate](),\n month = date[D.hcGetMonth](),\n fullYear = date[D.hcGetFullYear](),\n lang = H.defaultOptions.lang,\n langWeekdays = lang.weekdays,\n shortWeekdays = lang.shortWeekdays,\n pad = H.pad,\n\n // List all format keys. Custom formats can be added from the outside. \n replacements = H.extend({\n\n //-- Day\n // Short weekday, like 'Mon'\n 'a': shortWeekdays ?\n shortWeekdays[day] : langWeekdays[day].substr(0, 3),\n // Long weekday, like 'Monday'\n 'A': langWeekdays[day],\n // Two digit day of the month, 01 to 31\n 'd': pad(dayOfMonth),\n // Day of the month, 1 through 31\n 'e': pad(dayOfMonth, 2, ' '),\n 'w': day,\n\n // Week (none implemented)\n //'W': weekNumber(),\n\n //-- Month\n // Short month, like 'Jan'\n 'b': lang.shortMonths[month],\n // Long month, like 'January'\n 'B': lang.months[month],\n // Two digit month number, 01 through 12\n 'm': pad(month + 1),\n\n //-- Year\n // Two digits year, like 09 for 2009\n 'y': fullYear.toString().substr(2, 2),\n // Four digits year, like 2009\n 'Y': fullYear,\n\n //-- Time\n // Two digits hours in 24h format, 00 through 23\n 'H': pad(hours),\n // Hours in 24h format, 0 through 23\n 'k': hours,\n // Two digits hours in 12h format, 00 through 11\n 'I': pad((hours % 12) || 12),\n // Hours in 12h format, 1 through 12\n 'l': (hours % 12) || 12,\n // Two digits minutes, 00 through 59\n 'M': pad(date[D.hcGetMinutes]()),\n // Upper case AM or PM\n 'p': hours < 12 ? 'AM' : 'PM',\n // Lower case AM or PM\n 'P': hours < 12 ? 'am' : 'pm',\n // Two digits seconds, 00 through 59\n 'S': pad(date.getSeconds()),\n // Milliseconds (naming from Ruby)\n 'L': pad(Math.round(timestamp % 1000), 3)\n },\n\n /**\n * A hook for defining additional date format specifiers. New\n * specifiers are defined as key-value pairs by using the specifier\n * as key, and a function which takes the timestamp as value. This\n * function returns the formatted portion of the date.\n *\n * @type {Object}\n * @name dateFormats\n * @memberOf Highcharts\n * @sample highcharts/global/dateformats/ Adding support for week\n * number\n */\n H.dateFormats\n );\n\n\n // Do the replaces\n H.objectEach(replacements, function(val, key) {\n // Regex would do it in one line, but this is faster\n while (format.indexOf('%' + key) !== -1) {\n format = format.replace(\n '%' + key,\n typeof val === 'function' ? val(timestamp) : val\n );\n }\n\n });\n\n // Optionally capitalize the string and return\n return capitalize ?\n format.substr(0, 1).toUpperCase() + format.substr(1) :\n format;\n };\n\n /**\n * Format a single variable. Similar to sprintf, without the % prefix.\n *\n * @example\n * formatSingle('.2f', 5); // => '5.00'.\n *\n * @function #formatSingle\n * @memberOf Highcharts\n * @param {String} format The format string.\n * @param {*} val The value.\n * @returns {String} The formatted representation of the value.\n */\n H.formatSingle = function(format, val) {\n var floatRegex = /f$/,\n decRegex = /\\.([0-9])/,\n lang = H.defaultOptions.lang,\n decimals;\n\n if (floatRegex.test(format)) { // float\n decimals = format.match(decRegex);\n decimals = decimals ? decimals[1] : -1;\n if (val !== null) {\n val = H.numberFormat(\n val,\n decimals,\n lang.decimalPoint,\n format.indexOf(',') > -1 ? lang.thousandsSep : ''\n );\n }\n } else {\n val = H.dateFormat(format, val);\n }\n return val;\n };\n\n /**\n * Format a string according to a subset of the rules of Python's String.format\n * method.\n *\n * @function #format\n * @memberOf Highcharts\n * @param {String} str The string to format.\n * @param {Object} ctx The context, a collection of key-value pairs where each\n * key is replaced by its value.\n * @returns {String} The formatted string.\n *\n * @example\n * var s = Highcharts.format(\n * 'The {color} fox was {len:.2f} feet long',\n * { color: 'red', len: Math.PI }\n * );\n * // => The red fox was 3.14 feet long\n */\n H.format = function(str, ctx) {\n var splitter = '{',\n isInside = false,\n segment,\n valueAndFormat,\n path,\n i,\n len,\n ret = [],\n val,\n index;\n\n while (str) {\n index = str.indexOf(splitter);\n if (index === -1) {\n break;\n }\n\n segment = str.slice(0, index);\n if (isInside) { // we're on the closing bracket looking back\n\n valueAndFormat = segment.split(':');\n path = valueAndFormat.shift().split('.'); // get first and leave\n len = path.length;\n val = ctx;\n\n // Assign deeper paths\n for (i = 0; i < len; i++) {\n val = val[path[i]];\n }\n\n // Format the replacement\n if (valueAndFormat.length) {\n val = H.formatSingle(valueAndFormat.join(':'), val);\n }\n\n // Push the result and advance the cursor\n ret.push(val);\n\n } else {\n ret.push(segment);\n\n }\n str = str.slice(index + 1); // the rest\n isInside = !isInside; // toggle\n splitter = isInside ? '}' : '{'; // now look for next matching bracket\n }\n ret.push(str);\n return ret.join('');\n };\n\n /**\n * Get the magnitude of a number.\n *\n * @function #getMagnitude\n * @memberOf Highcharts\n * @param {Number} number The number.\n * @returns {Number} The magnitude, where 1-9 are magnitude 1, 10-99 magnitude 2\n * etc.\n */\n H.getMagnitude = function(num) {\n return Math.pow(10, Math.floor(Math.log(num) / Math.LN10));\n };\n\n /**\n * Take an interval and normalize it to multiples of round numbers.\n *\n * @todo Move this function to the Axis prototype. It is here only for\n * historical reasons.\n * @function #normalizeTickInterval\n * @memberOf Highcharts\n * @param {Number} interval - The raw, un-rounded interval.\n * @param {Array} [multiples] - Allowed multiples.\n * @param {Number} [magnitude] - The magnitude of the number.\n * @param {Boolean} [allowDecimals] - Whether to allow decimals.\n * @param {Boolean} [hasTickAmount] - If it has tickAmount, avoid landing\n * on tick intervals lower than original.\n * @returns {Number} The normalized interval.\n */\n H.normalizeTickInterval = function(interval, multiples, magnitude,\n allowDecimals, hasTickAmount) {\n var normalized,\n i,\n retInterval = interval;\n\n // round to a tenfold of 1, 2, 2.5 or 5\n magnitude = H.pick(magnitude, 1);\n normalized = interval / magnitude;\n\n // multiples for a linear scale\n if (!multiples) {\n multiples = hasTickAmount ?\n // Finer grained ticks when the tick amount is hard set, including\n // when alignTicks is true on multiple axes (#4580).\n [1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10] :\n\n // Else, let ticks fall on rounder numbers\n [1, 2, 2.5, 5, 10];\n\n\n // the allowDecimals option\n if (allowDecimals === false) {\n if (magnitude === 1) {\n multiples = H.grep(multiples, function(num) {\n return num % 1 === 0;\n });\n } else if (magnitude <= 0.1) {\n multiples = [1 / magnitude];\n }\n }\n }\n\n // normalize the interval to the nearest multiple\n for (i = 0; i < multiples.length; i++) {\n retInterval = multiples[i];\n // only allow tick amounts smaller than natural\n if ((hasTickAmount && retInterval * magnitude >= interval) ||\n (!hasTickAmount && (normalized <= (multiples[i] +\n (multiples[i + 1] || multiples[i])) / 2))) {\n break;\n }\n }\n\n // Multiply back to the correct magnitude. Correct floats to appropriate \n // precision (#6085).\n retInterval = H.correctFloat(\n retInterval * magnitude, -Math.round(Math.log(0.001) / Math.LN10)\n );\n\n return retInterval;\n };\n\n\n /**\n * Sort an object array and keep the order of equal items. The ECMAScript\n * standard does not specify the behaviour when items are equal.\n *\n * @function #stableSort\n * @memberOf Highcharts\n * @param {Array} arr - The array to sort.\n * @param {Function} sortFunction - The function to sort it with, like with \n * regular Array.prototype.sort.\n * @returns {void}\n */\n H.stableSort = function(arr, sortFunction) {\n var length = arr.length,\n sortValue,\n i;\n\n // Add index to each item\n for (i = 0; i < length; i++) {\n arr[i].safeI = i; // stable sort index\n }\n\n arr.sort(function(a, b) {\n sortValue = sortFunction(a, b);\n return sortValue === 0 ? a.safeI - b.safeI : sortValue;\n });\n\n // Remove index from items\n for (i = 0; i < length; i++) {\n delete arr[i].safeI; // stable sort index\n }\n };\n\n /**\n * Non-recursive method to find the lowest member of an array. `Math.min` raises\n * a maximum call stack size exceeded error in Chrome when trying to apply more\n * than 150.000 points. This method is slightly slower, but safe.\n *\n * @function #arrayMin\n * @memberOf Highcharts\n * @param {Array} data An array of numbers.\n * @returns {Number} The lowest number.\n */\n H.arrayMin = function(data) {\n var i = data.length,\n min = data[0];\n\n while (i--) {\n if (data[i] < min) {\n min = data[i];\n }\n }\n return min;\n };\n\n /**\n * Non-recursive method to find the lowest member of an array. `Math.max` raises\n * a maximum call stack size exceeded error in Chrome when trying to apply more\n * than 150.000 points. This method is slightly slower, but safe.\n *\n * @function #arrayMax\n * @memberOf Highcharts\n * @param {Array} data - An array of numbers.\n * @returns {Number} The highest number.\n */\n H.arrayMax = function(data) {\n var i = data.length,\n max = data[0];\n\n while (i--) {\n if (data[i] > max) {\n max = data[i];\n }\n }\n return max;\n };\n\n /**\n * Utility method that destroys any SVGElement instances that are properties on\n * the given object. It loops all properties and invokes destroy if there is a\n * destroy method. The property is then delete.\n *\n * @function #destroyObjectProperties\n * @memberOf Highcharts\n * @param {Object} obj - The object to destroy properties on.\n * @param {Object} [except] - Exception, do not destroy this property, only\n * delete it.\n * @returns {void}\n */\n H.destroyObjectProperties = function(obj, except) {\n H.objectEach(obj, function(val, n) {\n // If the object is non-null and destroy is defined\n if (val && val !== except && val.destroy) {\n // Invoke the destroy\n val.destroy();\n }\n\n // Delete the property from the object.\n delete obj[n];\n });\n };\n\n\n /**\n * Discard a HTML element by moving it to the bin and delete.\n *\n * @function #discardElement\n * @memberOf Highcharts\n * @param {HTMLDOMElement} element - The HTML node to discard.\n * @returns {void}\n */\n H.discardElement = function(element) {\n var garbageBin = H.garbageBin;\n // create a garbage bin element, not part of the DOM\n if (!garbageBin) {\n garbageBin = H.createElement('div');\n }\n\n // move the node and empty bin\n if (element) {\n garbageBin.appendChild(element);\n }\n garbageBin.innerHTML = '';\n };\n\n /**\n * Fix JS round off float errors.\n *\n * @function #correctFloat\n * @memberOf Highcharts\n * @param {Number} num - A float number to fix.\n * @param {Number} [prec=14] - The precision.\n * @returns {Number} The corrected float number.\n */\n H.correctFloat = function(num, prec) {\n return parseFloat(\n num.toPrecision(prec || 14)\n );\n };\n\n /**\n * Set the global animation to either a given value, or fall back to the given\n * chart's animation option.\n *\n * @function #setAnimation\n * @memberOf Highcharts\n * @param {Boolean|Animation} animation - The animation object.\n * @param {Object} chart - The chart instance.\n * @returns {void}\n * @todo This function always relates to a chart, and sets a property on the\n * renderer, so it should be moved to the SVGRenderer.\n */\n H.setAnimation = function(animation, chart) {\n chart.renderer.globalAnimation = H.pick(\n animation,\n chart.options.chart.animation,\n true\n );\n };\n\n /**\n * Get the animation in object form, where a disabled animation is always\n * returned as `{ duration: 0 }`.\n *\n * @function #animObject\n * @memberOf Highcharts\n * @param {Boolean|AnimationOptions} animation - An animation setting. Can be an\n * object with duration, complete and easing properties, or a boolean to\n * enable or disable.\n * @returns {AnimationOptions} An object with at least a duration property.\n */\n H.animObject = function(animation) {\n return H.isObject(animation) ?\n H.merge(animation) : {\n duration: animation ? 500 : 0\n };\n };\n\n /**\n * The time unit lookup\n */\n H.timeUnits = {\n millisecond: 1,\n second: 1000,\n minute: 60000,\n hour: 3600000,\n day: 24 * 3600000,\n week: 7 * 24 * 3600000,\n month: 28 * 24 * 3600000,\n year: 364 * 24 * 3600000\n };\n\n /**\n * Format a number and return a string based on input settings.\n *\n * @function #numberFormat\n * @memberOf Highcharts\n * @param {Number} number - The input number to format.\n * @param {Number} decimals - The amount of decimals. A value of -1 preserves\n * the amount in the input number.\n * @param {String} [decimalPoint] - The decimal point, defaults to the one given\n * in the lang options, or a dot.\n * @param {String} [thousandsSep] - The thousands separator, defaults to the one\n * given in the lang options, or a space character.\n * @returns {String} The formatted number.\n *\n * @sample members/highcharts-numberformat/ Custom number format\n */\n H.numberFormat = function(number, decimals, decimalPoint, thousandsSep) {\n number = +number || 0;\n decimals = +decimals;\n\n var lang = H.defaultOptions.lang,\n origDec = (number.toString().split('.')[1] || '').length,\n strinteger,\n thousands,\n ret,\n roundedNumber;\n\n if (decimals === -1) {\n // Preserve decimals. Not huge numbers (#3793).\n decimals = Math.min(origDec, 20);\n } else if (!H.isNumber(decimals)) {\n decimals = 2;\n }\n\n // Add another decimal to avoid rounding errors of float numbers. (#4573)\n // Then use toFixed to handle rounding.\n roundedNumber = (\n Math.abs(number) + Math.pow(10, -Math.max(decimals, origDec) - 1)\n ).toFixed(decimals);\n\n // A string containing the positive integer component of the number\n strinteger = String(H.pInt(roundedNumber));\n\n // Leftover after grouping into thousands. Can be 0, 1 or 3.\n thousands = strinteger.length > 3 ? strinteger.length % 3 : 0;\n\n // Language\n decimalPoint = H.pick(decimalPoint, lang.decimalPoint);\n thousandsSep = H.pick(thousandsSep, lang.thousandsSep);\n\n // Start building the return\n ret = number < 0 ? '-' : '';\n\n // Add the leftover after grouping into thousands. For example, in the\n // number 42 000 000, this line adds 42.\n ret += thousands ? strinteger.substr(0, thousands) + thousandsSep : '';\n\n // Add the remaining thousands groups, joined by the thousands separator\n ret += strinteger\n .substr(thousands)\n .replace(/(\\d{3})(?=\\d)/g, '$1' + thousandsSep);\n\n // Add the decimal point and the decimal component\n if (decimals) {\n // Get the decimal component\n ret += decimalPoint + roundedNumber.slice(-decimals);\n }\n\n return ret;\n };\n\n /**\n * Easing definition\n * @ignore\n * @param {Number} pos Current position, ranging from 0 to 1.\n */\n Math.easeInOutSine = function(pos) {\n return -0.5 * (Math.cos(Math.PI * pos) - 1);\n };\n\n /**\n * Get the computed CSS value for given element and property, only for numerical\n * properties. For width and height, the dimension of the inner box (excluding\n * padding) is returned. Used for fitting the chart within the container.\n *\n * @function #getStyle\n * @memberOf Highcharts\n * @param {HTMLDOMElement} el - A HTML element.\n * @param {String} prop - The property name.\n * @param {Boolean} [toInt=true] - Parse to integer.\n * @returns {Number} - The numeric value.\n */\n H.getStyle = function(el, prop, toInt) {\n\n var style;\n\n // For width and height, return the actual inner pixel size (#4913)\n if (prop === 'width') {\n return Math.min(el.offsetWidth, el.scrollWidth) -\n H.getStyle(el, 'padding-left') -\n H.getStyle(el, 'padding-right');\n } else if (prop === 'height') {\n return Math.min(el.offsetHeight, el.scrollHeight) -\n H.getStyle(el, 'padding-top') -\n H.getStyle(el, 'padding-bottom');\n }\n\n // Otherwise, get the computed style\n style = win.getComputedStyle(el, undefined);\n if (style) {\n style = style.getPropertyValue(prop);\n if (H.pick(toInt, true)) {\n style = H.pInt(style);\n }\n }\n return style;\n };\n\n /**\n * Search for an item in an array.\n *\n * @function #inArray\n * @memberOf Highcharts\n * @param {*} item - The item to search for.\n * @param {arr} arr - The array or node collection to search in.\n * @returns {Number} - The index within the array, or -1 if not found.\n */\n H.inArray = function(item, arr) {\n return arr.indexOf ? arr.indexOf(item) : [].indexOf.call(arr, item);\n };\n\n /**\n * Filter an array by a callback.\n *\n * @function #grep\n * @memberOf Highcharts\n * @param {Array} arr - The array to filter.\n * @param {Function} callback - The callback function. The function receives the\n * item as the first argument. Return `true` if the item is to be\n * preserved.\n * @returns {Array} - A new, filtered array.\n */\n H.grep = function(arr, callback) {\n return [].filter.call(arr, callback);\n };\n\n /**\n * Return the value of the first element in the array that satisfies the \n * provided testing function.\n *\n * @function #find\n * @memberOf Highcharts\n * @param {Array} arr - The array to test.\n * @param {Function} callback - The callback function. The function receives the\n * item as the first argument. Return `true` if this item satisfies the\n * condition.\n * @returns {Mixed} - The value of the element.\n */\n H.find = function(arr, callback) {\n return [].find.call(arr, callback);\n };\n\n /**\n * Map an array by a callback.\n *\n * @function #map\n * @memberOf Highcharts\n * @param {Array} arr - The array to map.\n * @param {Function} fn - The callback function. Return the new value for the \n * new array.\n * @returns {Array} - A new array item with modified items.\n */\n H.map = function(arr, fn) {\n var results = [],\n i = 0,\n len = arr.length;\n\n for (; i < len; i++) {\n results[i] = fn.call(arr[i], arr[i], i, arr);\n }\n\n return results;\n };\n\n /**\n * Get the element's offset position, corrected for `overflow: auto`.\n *\n * @function #offset\n * @memberOf Highcharts\n * @param {HTMLDOMElement} el - The HTML element.\n * @returns {Object} An object containing `left` and `top` properties for the\n * position in the page.\n */\n H.offset = function(el) {\n var docElem = doc.documentElement,\n box = el.getBoundingClientRect();\n\n return {\n top: box.top + (win.pageYOffset || docElem.scrollTop) -\n (docElem.clientTop || 0),\n left: box.left + (win.pageXOffset || docElem.scrollLeft) -\n (docElem.clientLeft || 0)\n };\n };\n\n /**\n * Stop running animation.\n *\n * @todo A possible extension to this would be to stop a single property, when\n * we want to continue animating others. Then assign the prop to the timer\n * in the Fx.run method, and check for the prop here. This would be an\n * improvement in all cases where we stop the animation from .attr. Instead of\n * stopping everything, we can just stop the actual attributes we're setting.\n *\n * @function #stop\n * @memberOf Highcharts\n * @param {SVGElement} el - The SVGElement to stop animation on.\n * @param {string} [prop] - The property to stop animating. If given, the stop\n * method will stop a single property from animating, while others continue.\n * @returns {void}\n */\n H.stop = function(el, prop) {\n\n var i = timers.length;\n\n // Remove timers related to this element (#4519)\n while (i--) {\n if (timers[i].elem === el && (!prop || prop === timers[i].prop)) {\n timers[i].stopped = true; // #4667\n }\n }\n };\n\n /**\n * Iterate over an array.\n *\n * @function #each\n * @memberOf Highcharts\n * @param {Array} arr - The array to iterate over.\n * @param {Function} fn - The iterator callback. It passes three arguments:\n * * item - The array item.\n * * index - The item's index in the array.\n * * arr - The array that each is being applied to.\n * @param {Object} [ctx] The context.\n */\n H.each = function(arr, fn, ctx) { // modern browsers\n return Array.prototype.forEach.call(arr, fn, ctx);\n };\n\n /**\n * Iterate over object key pairs in an object.\n *\n * @function #objectEach\n * @memberOf Highcharts\n * @param {Object} obj - The object to iterate over.\n * @param {Function} fn - The iterator callback. It passes three arguments:\n * * value - The property value.\n * * key - The property key.\n * * obj - The object that objectEach is being applied to.\n * @param {Object} ctx The context\n */\n H.objectEach = function(obj, fn, ctx) {\n for (var key in obj) {\n if (obj.hasOwnProperty(key)) {\n fn.call(ctx, obj[key], key, obj);\n }\n }\n };\n\n /**\n * Add an event listener.\n *\n * @function #addEvent\n * @memberOf Highcharts\n * @param {Object} el - The element or object to add a listener to. It can be a\n * {@link HTMLDOMElement}, an {@link SVGElement} or any other object.\n * @param {String} type - The event type.\n * @param {Function} fn - The function callback to execute when the event is \n * fired.\n * @returns {Function} A callback function to remove the added event.\n */\n H.addEvent = function(el, type, fn) {\n\n var events = el.hcEvents = el.hcEvents || {};\n\n function wrappedFn(e) {\n e.target = e.srcElement || win; // #2820\n fn.call(el, e);\n }\n\n // Handle DOM events in modern browsers\n if (el.addEventListener) {\n el.addEventListener(type, fn, false);\n\n // Handle old IE implementation\n } else if (el.attachEvent) {\n\n if (!el.hcEventsIE) {\n el.hcEventsIE = {};\n }\n\n // Link wrapped fn with original fn, so we can get this in removeEvent\n el.hcEventsIE[fn.toString()] = wrappedFn;\n\n el.attachEvent('on' + type, wrappedFn);\n }\n\n if (!events[type]) {\n events[type] = [];\n }\n\n events[type].push(fn);\n\n // Return a function that can be called to remove this event.\n return function() {\n H.removeEvent(el, type, fn);\n };\n };\n\n /**\n * Remove an event that was added with {@link Highcharts#addEvent}.\n *\n * @function #removeEvent\n * @memberOf Highcharts\n * @param {Object} el - The element to remove events on.\n * @param {String} [type] - The type of events to remove. If undefined, all\n * events are removed from the element.\n * @param {Function} [fn] - The specific callback to remove. If undefined, all\n * events that match the element and optionally the type are removed.\n * @returns {void}\n */\n H.removeEvent = function(el, type, fn) {\n\n var events,\n hcEvents = el.hcEvents,\n index;\n\n function removeOneEvent(type, fn) {\n if (el.removeEventListener) {\n el.removeEventListener(type, fn, false);\n } else if (el.attachEvent) {\n fn = el.hcEventsIE[fn.toString()];\n el.detachEvent('on' + type, fn);\n }\n }\n\n function removeAllEvents() {\n var types,\n len;\n\n if (!el.nodeName) {\n return; // break on non-DOM events\n }\n\n if (type) {\n types = {};\n types[type] = true;\n } else {\n types = hcEvents;\n }\n\n H.objectEach(types, function(val, n) {\n if (hcEvents[n]) {\n len = hcEvents[n].length;\n while (len--) {\n removeOneEvent(n, hcEvents[n][len]);\n }\n }\n });\n }\n\n if (hcEvents) {\n if (type) {\n events = hcEvents[type] || [];\n if (fn) {\n index = H.inArray(fn, events);\n if (index > -1) {\n events.splice(index, 1);\n hcEvents[type] = events;\n }\n removeOneEvent(type, fn);\n\n } else {\n removeAllEvents();\n hcEvents[type] = [];\n }\n } else {\n removeAllEvents();\n el.hcEvents = {};\n }\n }\n };\n\n /**\n * Fire an event that was registered with {@link Highcharts#addEvent}.\n *\n * @function #fireEvent\n * @memberOf Highcharts\n * @param {Object} el - The object to fire the event on. It can be a\n * {@link HTMLDOMElement}, an {@link SVGElement} or any other object.\n * @param {String} type - The type of event.\n * @param {Object} [eventArguments] - Custom event arguments that are passed on\n * as an argument to the event handler.\n * @param {Function} [defaultFunction] - The default function to execute if the \n * other listeners haven't returned false.\n * @returns {void}\n */\n H.fireEvent = function(el, type, eventArguments, defaultFunction) {\n var e,\n hcEvents = el.hcEvents,\n events,\n len,\n i,\n fn;\n\n eventArguments = eventArguments || {};\n\n if (doc.createEvent && (el.dispatchEvent || el.fireEvent)) {\n e = doc.createEvent('Events');\n e.initEvent(type, true, true);\n //e.target = el;\n\n H.extend(e, eventArguments);\n\n if (el.dispatchEvent) {\n el.dispatchEvent(e);\n } else {\n el.fireEvent(type, e);\n }\n\n } else if (hcEvents) {\n\n events = hcEvents[type] || [];\n len = events.length;\n\n if (!eventArguments.target) { // We're running a custom event\n\n H.extend(eventArguments, {\n // Attach a simple preventDefault function to skip default\n // handler if called. The built-in defaultPrevented property is\n // not overwritable (#5112)\n preventDefault: function() {\n eventArguments.defaultPrevented = true;\n },\n // Setting target to native events fails with clicking the\n // zoom-out button in Chrome.\n target: el,\n // If the type is not set, we're running a custom event (#2297).\n // If it is set, we're running a browser event, and setting it\n // will cause en error in IE8 (#2465). \n type: type\n });\n }\n\n\n for (i = 0; i < len; i++) {\n fn = events[i];\n\n // If the event handler return false, prevent the default handler\n // from executing\n if (fn && fn.call(el, eventArguments) === false) {\n eventArguments.preventDefault();\n }\n }\n }\n\n // Run the default if not prevented\n if (defaultFunction && !eventArguments.defaultPrevented) {\n defaultFunction(eventArguments);\n }\n };\n\n /**\n * An animation configuration. Animation configurations can also be defined as\n * booleans, where `false` turns off animation and `true` defaults to a duration\n * of 500ms.\n * @typedef {Object} AnimationOptions\n * @property {Number} duration - The animation duration in milliseconds.\n * @property {String} [easing] - The name of an easing function as defined on\n * the `Math` object.\n * @property {Function} [complete] - A callback function to exectute when the\n * animation finishes.\n * @property {Function} [step] - A callback function to execute on each step of\n * each attribute or CSS property that's being animated. The first argument\n * contains information about the animation and progress.\n */\n\n\n /**\n * The global animate method, which uses Fx to create individual animators.\n *\n * @function #animate\n * @memberOf Highcharts\n * @param {HTMLDOMElement|SVGElement} el - The element to animate.\n * @param {Object} params - An object containing key-value pairs of the\n * properties to animate. Supports numeric as pixel-based CSS properties\n * for HTML objects and attributes for SVGElements.\n * @param {AnimationOptions} [opt] - Animation options.\n */\n H.animate = function(el, params, opt) {\n var start,\n unit = '',\n end,\n fx,\n args;\n\n if (!H.isObject(opt)) { // Number or undefined/null\n args = arguments;\n opt = {\n duration: args[2],\n easing: args[3],\n complete: args[4]\n };\n }\n if (!H.isNumber(opt.duration)) {\n opt.duration = 400;\n }\n opt.easing = typeof opt.easing === 'function' ?\n opt.easing :\n (Math[opt.easing] || Math.easeInOutSine);\n opt.curAnim = H.merge(params);\n\n H.objectEach(params, function(val, prop) {\n // Stop current running animation of this property\n H.stop(el, prop);\n\n fx = new H.Fx(el, opt, prop);\n end = null;\n\n if (prop === 'd') {\n fx.paths = fx.initPath(\n el,\n el.d,\n params.d\n );\n fx.toD = params.d;\n start = 0;\n end = 1;\n } else if (el.attr) {\n start = el.attr(prop);\n } else {\n start = parseFloat(H.getStyle(el, prop)) || 0;\n if (prop !== 'opacity') {\n unit = 'px';\n }\n }\n\n if (!end) {\n end = val;\n }\n if (end && end.match && end.match('px')) {\n end = end.replace(/px/g, ''); // #4351\n }\n fx.run(start, end, unit);\n });\n };\n\n /**\n * Factory to create new series prototypes.\n *\n * @function #seriesType\n * @memberOf Highcharts\n *\n * @param {String} type - The series type name.\n * @param {String} parent - The parent series type name. Use `line` to inherit\n * from the basic {@link Series} object.\n * @param {Object} options - The additional default options that is merged with\n * the parent's options.\n * @param {Object} props - The properties (functions and primitives) to set on\n * the new prototype.\n * @param {Object} [pointProps] - Members for a series-specific extension of the\n * {@link Point} prototype if needed.\n * @returns {*} - The newly created prototype as extended from {@link Series}\n * or its derivatives.\n */\n // docs: add to API + extending Highcharts\n H.seriesType = function(type, parent, options, props, pointProps) {\n var defaultOptions = H.getOptions(),\n seriesTypes = H.seriesTypes;\n\n if (seriesTypes[type]) {\n return H.error(27); // Series type already defined\n }\n\n // Merge the options\n defaultOptions.plotOptions[type] = H.merge(\n defaultOptions.plotOptions[parent],\n options\n );\n\n // Create the class\n seriesTypes[type] = H.extendClass(seriesTypes[parent] ||\n function() {}, props);\n seriesTypes[type].prototype.type = type;\n\n // Create the point class if needed\n if (pointProps) {\n seriesTypes[type].prototype.pointClass =\n H.extendClass(H.Point, pointProps);\n }\n\n return seriesTypes[type];\n };\n\n /**\n * Get a unique key for using in internal element id's and pointers. The key\n * is composed of a random hash specific to this Highcharts instance, and a \n * counter.\n * @function #uniqueKey\n * @memberOf Highcharts\n * @return {string} The key.\n * @example\n * var id = H.uniqueKey(); // => 'highcharts-x45f6hp-0'\n */\n H.uniqueKey = (function() {\n\n var uniqueKeyHash = Math.random().toString(36).substring(2, 9),\n idCounter = 0;\n\n return function() {\n return 'highcharts-' + uniqueKeyHash + '-' + idCounter++;\n };\n }());\n\n /**\n * Register Highcharts as a plugin in jQuery\n */\n if (jQuery) {\n jQuery.fn.highcharts = function() {\n var args = [].slice.call(arguments);\n\n if (this[0]) { // this[0] is the renderTo div\n\n // Create the chart\n if (args[0]) {\n new H[ // eslint-disable-line no-new\n // Constructor defaults to Chart\n H.isString(args[0]) ? args.shift() : 'Chart'\n ](this[0], args[0], args[1]);\n return this;\n }\n\n // When called without parameters or with the return argument,\n // return an existing chart\n return charts[H.attr(this[0], 'data-highcharts-chart')];\n }\n };\n }\n\n\n /**\n * Compatibility section to add support for legacy IE. This can be removed if\n * old IE support is not needed.\n */\n if (doc && !doc.defaultView) {\n H.getStyle = function(el, prop) {\n var val,\n alias = {\n width: 'clientWidth',\n height: 'clientHeight'\n }[prop];\n\n if (el.style[prop]) {\n return H.pInt(el.style[prop]);\n }\n if (prop === 'opacity') {\n prop = 'filter';\n }\n\n // Getting the rendered width and height\n if (alias) {\n el.style.zoom = 1;\n return Math.max(el[alias] - 2 * H.getStyle(el, 'padding'), 0);\n }\n\n val = el.currentStyle[prop.replace(/\\-(\\w)/g, function(a, b) {\n return b.toUpperCase();\n })];\n if (prop === 'filter') {\n val = val.replace(\n /alpha\\(opacity=([0-9]+)\\)/,\n function(a, b) {\n return b / 100;\n }\n );\n }\n\n return val === '' ? 1 : H.pInt(val);\n };\n }\n\n if (!Array.prototype.forEach) {\n H.each = function(arr, fn, ctx) { // legacy\n var i = 0,\n len = arr.length;\n for (; i < len; i++) {\n if (fn.call(ctx, arr[i], i, arr) === false) {\n return i;\n }\n }\n };\n }\n\n if (!Array.prototype.indexOf) {\n H.inArray = function(item, arr) {\n var len,\n i = 0;\n\n if (arr) {\n len = arr.length;\n\n for (; i < len; i++) {\n if (arr[i] === item) {\n return i;\n }\n }\n }\n\n return -1;\n };\n }\n\n if (!Array.prototype.filter) {\n H.grep = function(elements, fn) {\n var ret = [],\n i = 0,\n length = elements.length;\n\n for (; i < length; i++) {\n if (fn(elements[i], i)) {\n ret.push(elements[i]);\n }\n }\n\n return ret;\n };\n }\n\n if (!Array.prototype.find) {\n H.find = function(arr, fn) {\n var i,\n length = arr.length;\n\n for (i = 0; i < length; i++) {\n if (fn(arr[i], i)) {\n return arr[i];\n }\n }\n };\n }\n\n //--- End compatibility section ---\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var each = H.each,\n isNumber = H.isNumber,\n map = H.map,\n merge = H.merge,\n pInt = H.pInt;\n\n /**\n * @typedef {string} ColorString\n * A valid color to be parsed and handled by Highcharts. Highcharts internally \n * supports hex colors like `#ffffff`, rgb colors like `rgb(255,255,255)` and\n * rgba colors like `rgba(255,255,255,1)`. Other colors may be supported by the\n * browsers and displayed correctly, but Highcharts is not able to process them\n * and apply concepts like opacity and brightening.\n */\n /**\n * Handle color operations. The object methods are chainable.\n * @param {String} input The input color in either rbga or hex format\n */\n H.Color = function(input) {\n // Backwards compatibility, allow instanciation without new\n if (!(this instanceof H.Color)) {\n return new H.Color(input);\n }\n // Initialize\n this.init(input);\n };\n H.Color.prototype = {\n\n // Collection of parsers. This can be extended from the outside by pushing parsers\n // to Highcharts.Color.prototype.parsers.\n parsers: [{\n // RGBA color\n regex: /rgba\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]?(?:\\.[0-9]+)?)\\s*\\)/,\n parse: function(result) {\n return [pInt(result[1]), pInt(result[2]), pInt(result[3]), parseFloat(result[4], 10)];\n }\n }, {\n // RGB color\n regex: /rgb\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*\\)/,\n parse: function(result) {\n return [pInt(result[1]), pInt(result[2]), pInt(result[3]), 1];\n }\n }],\n\n // Collection of named colors. Can be extended from the outside by adding\n // colors to Highcharts.Color.prototype.names.\n names: {\n none: 'rgba(255,255,255,0)',\n white: '#ffffff',\n black: '#000000'\n },\n\n /**\n * Parse the input color to rgba array\n * @param {String} input\n */\n init: function(input) {\n var result,\n rgba,\n i,\n parser,\n len;\n\n this.input = input = this.names[\n input && input.toLowerCase ?\n input.toLowerCase() :\n ''\n ] || input;\n\n // Gradients\n if (input && input.stops) {\n this.stops = map(input.stops, function(stop) {\n return new H.Color(stop[1]);\n });\n\n // Solid colors\n } else {\n\n // Check if it's possible to do bitmasking instead of regex\n if (input && input[0] === '#') {\n\n len = input.length;\n input = parseInt(input.substr(1), 16);\n\n // Handle long-form, e.g. #AABBCC\n if (len === 7) {\n\n rgba = [\n (input & 0xFF0000) >> 16,\n (input & 0xFF00) >> 8,\n (input & 0xFF),\n 1\n ];\n\n // Handle short-form, e.g. #ABC\n // In short form, the value is assumed to be the same \n // for both nibbles for each component. e.g. #ABC = #AABBCC\n } else if (len === 4) {\n\n rgba = [\n ((input & 0xF00) >> 4) | (input & 0xF00) >> 8,\n ((input & 0xF0) >> 4) | (input & 0xF0),\n ((input & 0xF) << 4) | (input & 0xF),\n 1\n ];\n }\n }\n\n // Otherwise, check regex parsers\n if (!rgba) {\n i = this.parsers.length;\n while (i-- && !rgba) {\n parser = this.parsers[i];\n result = parser.regex.exec(input);\n if (result) {\n rgba = parser.parse(result);\n }\n }\n }\n }\n this.rgba = rgba || [];\n },\n\n /**\n * Return the color a specified format\n * @param {String} format\n */\n get: function(format) {\n var input = this.input,\n rgba = this.rgba,\n ret;\n\n if (this.stops) {\n ret = merge(input);\n ret.stops = [].concat(ret.stops);\n each(this.stops, function(stop, i) {\n ret.stops[i] = [ret.stops[i][0], stop.get(format)];\n });\n\n // it's NaN if gradient colors on a column chart\n } else if (rgba && isNumber(rgba[0])) {\n if (format === 'rgb' || (!format && rgba[3] === 1)) {\n ret = 'rgb(' + rgba[0] + ',' + rgba[1] + ',' + rgba[2] + ')';\n } else if (format === 'a') {\n ret = rgba[3];\n } else {\n ret = 'rgba(' + rgba.join(',') + ')';\n }\n } else {\n ret = input;\n }\n return ret;\n },\n\n /**\n * Brighten the color\n * @param {Number} alpha\n */\n brighten: function(alpha) {\n var i,\n rgba = this.rgba;\n\n if (this.stops) {\n each(this.stops, function(stop) {\n stop.brighten(alpha);\n });\n\n } else if (isNumber(alpha) && alpha !== 0) {\n for (i = 0; i < 3; i++) {\n rgba[i] += pInt(alpha * 255);\n\n if (rgba[i] < 0) {\n rgba[i] = 0;\n }\n if (rgba[i] > 255) {\n rgba[i] = 255;\n }\n }\n }\n return this;\n },\n\n /**\n * Set the color's opacity to a given alpha value\n * @param {Number} alpha\n */\n setOpacity: function(alpha) {\n this.rgba[3] = alpha;\n return this;\n },\n\n /*\n * Return an intermediate color between two colors.\n *\n * @param {Highcharts.Color} to\n * The color object to tween to.\n * @param {Number} pos\n * The intermediate position, where 0 is the from color (current\n * color item), and 1 is the `to` color.\n *\n * @return {String}\n * The intermediate color in rgba notation.\n */\n tweenTo: function(to, pos) {\n // Check for has alpha, because rgba colors perform worse due to lack of\n // support in WebKit.\n var from = this,\n hasAlpha,\n ret;\n\n // Unsupported color, return to-color (#3920)\n if (!to.rgba.length) {\n ret = to.input || 'none';\n\n // Interpolate\n } else {\n from = from.rgba;\n to = to.rgba;\n hasAlpha = (to[3] !== 1 || from[3] !== 1);\n ret = (hasAlpha ? 'rgba(' : 'rgb(') +\n Math.round(to[0] + (from[0] - to[0]) * (1 - pos)) + ',' +\n Math.round(to[1] + (from[1] - to[1]) * (1 - pos)) + ',' +\n Math.round(to[2] + (from[2] - to[2]) * (1 - pos)) +\n (hasAlpha ?\n (',' + (to[3] + (from[3] - to[3]) * (1 - pos))) :\n '') + ')';\n }\n return ret;\n }\n };\n H.color = function(input) {\n return new H.Color(input);\n };\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var SVGElement,\n SVGRenderer,\n\n addEvent = H.addEvent,\n animate = H.animate,\n attr = H.attr,\n charts = H.charts,\n color = H.color,\n css = H.css,\n createElement = H.createElement,\n defined = H.defined,\n deg2rad = H.deg2rad,\n destroyObjectProperties = H.destroyObjectProperties,\n doc = H.doc,\n each = H.each,\n extend = H.extend,\n erase = H.erase,\n grep = H.grep,\n hasTouch = H.hasTouch,\n inArray = H.inArray,\n isArray = H.isArray,\n isFirefox = H.isFirefox,\n isMS = H.isMS,\n isObject = H.isObject,\n isString = H.isString,\n isWebKit = H.isWebKit,\n merge = H.merge,\n noop = H.noop,\n objectEach = H.objectEach,\n pick = H.pick,\n pInt = H.pInt,\n removeEvent = H.removeEvent,\n splat = H.splat,\n stop = H.stop,\n svg = H.svg,\n SVG_NS = H.SVG_NS,\n symbolSizes = H.symbolSizes,\n win = H.win;\n\n /**\n * @typedef {Object} SVGDOMElement - An SVG DOM element.\n */\n /**\n * The SVGElement prototype is a JavaScript wrapper for SVG elements used in the\n * rendering layer of Highcharts. Combined with the {@link\n * Highcharts.SVGRenderer} object, these prototypes allow freeform annotation\n * in the charts or even in HTML pages without instanciating a chart. The\n * SVGElement can also wrap HTML labels, when `text` or `label` elements are\n * created with the `useHTML` parameter.\n *\n * The SVGElement instances are created through factory functions on the \n * {@link Highcharts.SVGRenderer} object, like\n * [rect]{@link Highcharts.SVGRenderer#rect}, [path]{@link\n * Highcharts.SVGRenderer#path}, [text]{@link Highcharts.SVGRenderer#text},\n * [label]{@link Highcharts.SVGRenderer#label}, [g]{@link\n * Highcharts.SVGRenderer#g} and more.\n *\n * @class Highcharts.SVGElement\n */\n SVGElement = H.SVGElement = function() {\n return this;\n };\n extend(SVGElement.prototype, /** @lends Highcharts.SVGElement.prototype */ {\n\n // Default base for animation\n opacity: 1,\n SVG_NS: SVG_NS,\n\n /**\n * For labels, these CSS properties are applied to the `text` node directly.\n * @type {Array.}\n */\n textProps: ['direction', 'fontSize', 'fontWeight', 'fontFamily',\n 'fontStyle', 'color', 'lineHeight', 'width', 'textAlign',\n 'textDecoration', 'textOverflow', 'textOutline'\n ],\n\n /**\n * Initialize the SVG renderer. This function only exists to make the\n * initiation process overridable. It should not be called directly.\n *\n * @param {HighchartsSVGRenderer} renderer\n * The SVGRenderer instance to initialize to.\n * @param {String} nodeName\n * The SVG node name.\n * @returns {void}\n */\n init: function(renderer, nodeName) {\n\n /** \n * The DOM node. Each SVGRenderer instance wraps a main DOM node, but \n * may also represent more nodes.\n * @type {SVGDOMNode|HTMLDOMNode}\n */\n this.element = nodeName === 'span' ?\n createElement(nodeName) :\n doc.createElementNS(this.SVG_NS, nodeName);\n\n /**\n * The renderer that the SVGElement belongs to.\n * @type {Highcharts.SVGRenderer}\n */\n this.renderer = renderer;\n },\n\n /**\n * Animate to given attributes or CSS properties.\n * \n * @param {SVGAttributes} params SVG attributes or CSS to animate.\n * @param {AnimationOptions} [options] Animation options.\n * @param {Function} [complete] Function to perform at the end of animation.\n *\n * @sample highcharts/members/element-on/\n * Setting some attributes by animation\n * \n * @returns {Highcharts.SVGElement} Returns the SVGElement for chaining.\n */\n animate: function(params, options, complete) {\n var animOptions = H.animObject(\n pick(options, this.renderer.globalAnimation, true)\n );\n if (animOptions.duration !== 0) {\n if (complete) { // allows using a callback with the global animation without overwriting it\n animOptions.complete = complete;\n }\n animate(this, params, animOptions);\n } else {\n this.attr(params, null, complete);\n if (animOptions.step) {\n animOptions.step.call(this);\n }\n }\n return this;\n },\n\n /**\n * @typedef {Object} GradientOptions\n * @property {Object} linearGradient Holds an object that defines the start\n * position and the end position relative to the shape.\n * @property {Number} linearGradient.x1 Start horizontal position of the\n * gradient. Ranges 0-1.\n * @property {Number} linearGradient.x2 End horizontal position of the\n * gradient. Ranges 0-1.\n * @property {Number} linearGradient.y1 Start vertical position of the\n * gradient. Ranges 0-1.\n * @property {Number} linearGradient.y2 End vertical position of the\n * gradient. Ranges 0-1.\n * @property {Object} radialGradient Holds an object that defines the center\n * position and the radius.\n * @property {Number} radialGradient.cx Center horizontal position relative\n * to the shape. Ranges 0-1.\n * @property {Number} radialGradient.cy Center vertical position relative\n * to the shape. Ranges 0-1.\n * @property {Number} radialGradient.r Radius relative to the shape. Ranges\n * 0-1.\n * @property {Array.} stops The first item in each tuple is the\n * position in the gradient, where 0 is the start of the gradient and 1\n * is the end of the gradient. Multiple stops can be applied. The second\n * item is the color for each stop. This color can also be given in the\n * rgba format.\n *\n * @example\n * // Linear gradient used as a color option\n * color: {\n * linearGradient: { x1: 0, x2: 0, y1: 0, y2: 1 },\n * stops: [\n * [0, '#003399'], // start\n * [0.5, '#ffffff'], // middle\n * [1, '#3366AA'] // end\n * ]\n * }\n * }\n */\n /**\n * Build and apply an SVG gradient out of a common JavaScript configuration\n * object. This function is called from the attribute setters.\n *\n * @private\n * @param {GradientOptions} color The gradient options structure.\n * @param {string} prop The property to apply, can either be `fill` or\n * `stroke`. \n * @param {SVGDOMElement} elem SVG DOM element to apply the gradient on.\n */\n colorGradient: function(color, prop, elem) {\n var renderer = this.renderer,\n colorObject,\n gradName,\n gradAttr,\n radAttr,\n gradients,\n gradientObject,\n stops,\n stopColor,\n stopOpacity,\n radialReference,\n id,\n key = [],\n value;\n\n // Apply linear or radial gradients\n if (color.radialGradient) {\n gradName = 'radialGradient';\n } else if (color.linearGradient) {\n gradName = 'linearGradient';\n }\n\n if (gradName) {\n gradAttr = color[gradName];\n gradients = renderer.gradients;\n stops = color.stops;\n radialReference = elem.radialReference;\n\n // Keep < 2.2 kompatibility\n if (isArray(gradAttr)) {\n color[gradName] = gradAttr = {\n x1: gradAttr[0],\n y1: gradAttr[1],\n x2: gradAttr[2],\n y2: gradAttr[3],\n gradientUnits: 'userSpaceOnUse'\n };\n }\n\n // Correct the radial gradient for the radial reference system\n if (\n gradName === 'radialGradient' &&\n radialReference &&\n !defined(gradAttr.gradientUnits)\n ) {\n radAttr = gradAttr; // Save the radial attributes for updating\n gradAttr = merge(\n gradAttr,\n renderer.getRadialAttr(radialReference, radAttr), {\n gradientUnits: 'userSpaceOnUse'\n }\n );\n }\n\n // Build the unique key to detect whether we need to create a new element (#1282)\n objectEach(gradAttr, function(val, n) {\n if (n !== 'id') {\n key.push(n, val);\n }\n });\n objectEach(stops, function(val) {\n key.push(val);\n });\n key = key.join(',');\n\n // Check if a gradient object with the same config object is created within this renderer\n if (gradients[key]) {\n id = gradients[key].attr('id');\n\n } else {\n\n // Set the id and create the element\n gradAttr.id = id = H.uniqueKey();\n gradients[key] = gradientObject = renderer.createElement(gradName)\n .attr(gradAttr)\n .add(renderer.defs);\n\n gradientObject.radAttr = radAttr;\n\n // The gradient needs to keep a list of stops to be able to destroy them\n gradientObject.stops = [];\n each(stops, function(stop) {\n var stopObject;\n if (stop[1].indexOf('rgba') === 0) {\n colorObject = H.color(stop[1]);\n stopColor = colorObject.get('rgb');\n stopOpacity = colorObject.get('a');\n } else {\n stopColor = stop[1];\n stopOpacity = 1;\n }\n stopObject = renderer.createElement('stop').attr({\n offset: stop[0],\n 'stop-color': stopColor,\n 'stop-opacity': stopOpacity\n }).add(gradientObject);\n\n // Add the stop element to the gradient\n gradientObject.stops.push(stopObject);\n });\n }\n\n // Set the reference to the gradient object\n value = 'url(' + renderer.url + '#' + id + ')';\n elem.setAttribute(prop, value);\n elem.gradient = key;\n\n // Allow the color to be concatenated into tooltips formatters etc. (#2995)\n color.toString = function() {\n return value;\n };\n }\n },\n\n /**\n * Apply a text outline through a custom CSS property, by copying the text\n * element and apply stroke to the copy. Used internally. Contrast checks\n * at http://jsfiddle.net/highcharts/43soe9m1/2/ .\n *\n * @private\n * @param {String} textOutline A custom CSS `text-outline` setting, defined\n * by `width color`. \n * @example\n * // Specific color\n * text.css({\n * textOutline: '1px black'\n * });\n * // Automatic contrast\n * text.css({\n * color: '#000000', // black text\n * textOutline: '1px contrast' // => white outline\n * });\n */\n applyTextOutline: function(textOutline) {\n var elem = this.element,\n tspans,\n tspan,\n hasContrast = textOutline.indexOf('contrast') !== -1,\n styles = {},\n color,\n strokeWidth,\n firstRealChild,\n i;\n\n // When the text shadow is set to contrast, use dark stroke for light\n // text and vice versa.\n if (hasContrast) {\n styles.textOutline = textOutline = textOutline.replace(\n /contrast/g,\n this.renderer.getContrast(elem.style.fill)\n );\n }\n\n // Extract the stroke width and color\n textOutline = textOutline.split(' ');\n color = textOutline[textOutline.length - 1];\n strokeWidth = textOutline[0];\n\n if (strokeWidth && strokeWidth !== 'none' && H.svg) {\n\n this.fakeTS = true; // Fake text shadow\n\n tspans = [].slice.call(elem.getElementsByTagName('tspan'));\n\n // In order to get the right y position of the clone,\n // copy over the y setter\n this.ySetter = this.xSetter;\n\n // Since the stroke is applied on center of the actual outline, we\n // need to double it to get the correct stroke-width outside the \n // glyphs.\n strokeWidth = strokeWidth.replace(\n /(^[\\d\\.]+)(.*?)$/g,\n function(match, digit, unit) {\n return (2 * digit) + unit;\n }\n );\n\n // Remove shadows from previous runs. Iterate from the end to\n // support removing items inside the cycle (#6472).\n i = tspans.length;\n while (i--) {\n tspan = tspans[i];\n if (tspan.getAttribute('class') === 'highcharts-text-outline') {\n // Remove then erase\n erase(tspans, elem.removeChild(tspan));\n }\n }\n\n // For each of the tspans, create a stroked copy behind it.\n firstRealChild = elem.firstChild;\n each(tspans, function(tspan, y) {\n var clone;\n\n // Let the first line start at the correct X position\n if (y === 0) {\n tspan.setAttribute('x', elem.getAttribute('x'));\n y = elem.getAttribute('y');\n tspan.setAttribute('y', y || 0);\n if (y === null) {\n elem.setAttribute('y', 0);\n }\n }\n\n // Create the clone and apply outline properties\n clone = tspan.cloneNode(1);\n attr(clone, {\n 'class': 'highcharts-text-outline',\n 'fill': color,\n 'stroke': color,\n 'stroke-width': strokeWidth,\n 'stroke-linejoin': 'round'\n });\n elem.insertBefore(clone, firstRealChild);\n });\n }\n },\n\n /**\n *\n * @typedef {Object} SVGAttributes An object of key-value pairs for SVG\n * attributes. Attributes in Highcharts elements for the most parts\n * correspond to SVG, but some are specific to Highcharts, like `zIndex`,\n * `rotation`, `translateX`, `translateY`, `scaleX` and `scaleY`. SVG\n * attributes containing a hyphen are _not_ camel-cased, they should be\n * quoted to preserve the hyphen.\n * @example\n * {\n * 'stroke': '#ff0000', // basic\n * 'stroke-width': 2, // hyphenated\n * 'rotation': 45 // custom\n * 'd': ['M', 10, 10, 'L', 30, 30, 'z'] // path definition, note format\n * }\n */\n /**\n * Apply native and custom attributes to the SVG elements.\n * \n * In order to set the rotation center for rotation, set x and y to 0 and\n * use `translateX` and `translateY` attributes to position the element\n * instead.\n *\n * Attributes frequently used in Highcharts are `fill`, `stroke`,\n * `stroke-width`.\n *\n * @param {SVGAttributes|String} hash - The native and custom SVG\n * attributes. \n * @param {string} [val] - If the type of the first argument is `string`, \n * the second can be a value, which will serve as a single attribute\n * setter. If the first argument is a string and the second is undefined,\n * the function serves as a getter and the current value of the property\n * is returned.\n * @param {Function} [complete] - A callback function to execute after setting\n * the attributes. This makes the function compliant and interchangeable\n * with the {@link SVGElement#animate} function.\n * @param {boolean} [continueAnimation=true] Used internally when `.attr` is\n * called as part of an animation step. Otherwise, calling `.attr` for an\n * attribute will stop animation for that attribute.\n * \n * @returns {SVGElement|string|number} If used as a setter, it returns the \n * current {@link SVGElement} so the calls can be chained. If used as a \n * getter, the current value of the attribute is returned.\n *\n * @sample highcharts/members/renderer-rect/\n * Setting some attributes\n * \n * @example\n * // Set multiple attributes\n * element.attr({\n * stroke: 'red',\n * fill: 'blue',\n * x: 10,\n * y: 10\n * });\n *\n * // Set a single attribute\n * element.attr('stroke', 'red');\n *\n * // Get an attribute\n * element.attr('stroke'); // => 'red'\n * \n */\n attr: function(hash, val, complete, continueAnimation) {\n var key,\n element = this.element,\n hasSetSymbolSize,\n ret = this,\n skipAttr,\n setter;\n\n // single key-value pair\n if (typeof hash === 'string' && val !== undefined) {\n key = hash;\n hash = {};\n hash[key] = val;\n }\n\n // used as a getter: first argument is a string, second is undefined\n if (typeof hash === 'string') {\n ret = (this[hash + 'Getter'] || this._defaultGetter).call(this, hash, element);\n\n // setter\n } else {\n\n objectEach(hash, function(val, key) {\n skipAttr = false;\n\n // Unless .attr is from the animator update, stop current\n // running animation of this property\n if (!continueAnimation) {\n stop(this, key);\n }\n\n // Special handling of symbol attributes\n if (\n this.symbolName &&\n /^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)$/\n .test(key)\n ) {\n if (!hasSetSymbolSize) {\n this.symbolAttr(hash);\n hasSetSymbolSize = true;\n }\n skipAttr = true;\n }\n\n if (this.rotation && (key === 'x' || key === 'y')) {\n this.doTransform = true;\n }\n\n if (!skipAttr) {\n setter = this[key + 'Setter'] || this._defaultSetter;\n setter.call(this, val, key, element);\n\n\n // Let the shadow follow the main element\n if (this.shadows && /^(width|height|visibility|x|y|d|transform|cx|cy|r)$/.test(key)) {\n this.updateShadows(key, val, setter);\n }\n\n }\n }, this);\n\n this.afterSetters();\n }\n\n // In accordance with animate, run a complete callback\n if (complete) {\n complete();\n }\n\n return ret;\n },\n\n /**\n * This method is executed in the end of {attr}, after setting all attributes in the hash.\n * In can be used to efficiently consolidate multiple attributes in one SVG property -- e.g.,\n * translate, rotate and scale are merged in one \"transform\" attribute in the SVG node.\n */\n afterSetters: function() {\n // Update transform. Do this outside the loop to prevent redundant updating for batch setting\n // of attributes.\n if (this.doTransform) {\n this.updateTransform();\n this.doTransform = false;\n }\n },\n\n\n /**\n * Update the shadow elements with new attributes.\n *\n * @private\n * @param {String} key - The attribute name.\n * @param {String|Number} value - The value of the attribute.\n * @param {Function} setter - The setter function, inherited from the\n * parent wrapper\n * @returns {void}\n */\n updateShadows: function(key, value, setter) {\n var shadows = this.shadows,\n i = shadows.length;\n\n while (i--) {\n setter.call(\n shadows[i],\n key === 'height' ?\n Math.max(value - (shadows[i].cutHeight || 0), 0) :\n key === 'd' ? this.d : value,\n key,\n shadows[i]\n );\n }\n },\n\n\n /**\n * Add a class name to an element.\n *\n * @param {string} className - The new class name to add.\n * @param {boolean} [replace=false] - When true, the existing class name(s)\n * will be overwritten with the new one. When false, the new one is\n * added.\n * @returns {Highcharts.SVGElement} Return the SVG element for chainability.\n */\n addClass: function(className, replace) {\n var currentClassName = this.attr('class') || '';\n\n if (currentClassName.indexOf(className) === -1) {\n if (!replace) {\n className =\n (currentClassName + (currentClassName ? ' ' : '') +\n className).replace(' ', ' ');\n }\n this.attr('class', className);\n }\n return this;\n },\n\n /**\n * Check if an element has the given class name.\n * @param {string} className - The class name to check for.\n * @return {Boolean}\n */\n hasClass: function(className) {\n return attr(this.element, 'class').indexOf(className) !== -1;\n },\n\n /**\n * Remove a class name from the element.\n * @param {string} className The class name to remove.\n * @return {Highcharts.SVGElement} Returns the SVG element for chainability.\n */\n removeClass: function(className) {\n attr(this.element, 'class', (attr(this.element, 'class') || '').replace(className, ''));\n return this;\n },\n\n /**\n * If one of the symbol size affecting parameters are changed,\n * check all the others only once for each call to an element's\n * .attr() method\n * @param {Object} hash - The attributes to set.\n * @private\n */\n symbolAttr: function(hash) {\n var wrapper = this;\n\n each(['x', 'y', 'r', 'start', 'end', 'width', 'height', 'innerR', 'anchorX', 'anchorY'], function(key) {\n wrapper[key] = pick(hash[key], wrapper[key]);\n });\n\n wrapper.attr({\n d: wrapper.renderer.symbols[wrapper.symbolName](\n wrapper.x,\n wrapper.y,\n wrapper.width,\n wrapper.height,\n wrapper\n )\n });\n },\n\n /**\n * Apply a clipping rectangle to this element.\n * \n * @param {ClipRect} [clipRect] - The clipping rectangle. If skipped, the\n * current clip is removed.\n * @returns {Highcharts.SVGElement} Returns the SVG element to allow chaining.\n */\n clip: function(clipRect) {\n return this.attr(\n 'clip-path',\n clipRect ?\n 'url(' + this.renderer.url + '#' + clipRect.id + ')' :\n 'none'\n );\n },\n\n /**\n * Calculate the coordinates needed for drawing a rectangle crisply and\n * return the calculated attributes.\n * \n * @param {Object} rect - A rectangle.\n * @param {number} rect.x - The x position.\n * @param {number} rect.y - The y position.\n * @param {number} rect.width - The width.\n * @param {number} rect.height - The height.\n * @param {number} [strokeWidth] - The stroke width to consider when\n * computing crisp positioning. It can also be set directly on the rect\n * parameter.\n *\n * @returns {{x: Number, y: Number, width: Number, height: Number}} The\n * modified rectangle arguments.\n */\n crisp: function(rect, strokeWidth) {\n\n var wrapper = this,\n attribs = {},\n normalizer;\n\n strokeWidth = strokeWidth || rect.strokeWidth || 0;\n normalizer = Math.round(strokeWidth) % 2 / 2; // Math.round because strokeWidth can sometimes have roundoff errors\n\n // normalize for crisp edges\n rect.x = Math.floor(rect.x || wrapper.x || 0) + normalizer;\n rect.y = Math.floor(rect.y || wrapper.y || 0) + normalizer;\n rect.width = Math.floor((rect.width || wrapper.width || 0) - 2 * normalizer);\n rect.height = Math.floor((rect.height || wrapper.height || 0) - 2 * normalizer);\n if (defined(rect.strokeWidth)) {\n rect.strokeWidth = strokeWidth;\n }\n\n objectEach(rect, function(val, key) {\n if (wrapper[key] !== val) { // only set attribute if changed\n wrapper[key] = attribs[key] = val;\n }\n });\n\n return attribs;\n },\n\n /**\n * Set styles for the element. In addition to CSS styles supported by \n * native SVG and HTML elements, there are also some custom made for \n * Highcharts, like `width`, `ellipsis` and `textOverflow` for SVG text\n * elements.\n * @param {CSSObject} styles The new CSS styles.\n * @returns {Highcharts.SVGElement} Return the SVG element for chaining.\n *\n * @sample highcharts/members/renderer-text-on-chart/\n * Styled text\n */\n css: function(styles) {\n var oldStyles = this.styles,\n newStyles = {},\n elem = this.element,\n textWidth,\n serializedCss = '',\n hyphenate,\n hasNew = !oldStyles,\n // These CSS properties are interpreted internally by the SVG\n // renderer, but are not supported by SVG and should not be added to\n // the DOM. In styled mode, no CSS should find its way to the DOM\n // whatsoever (#6173, #6474).\n svgPseudoProps = ['textOutline', 'textOverflow', 'width'];\n\n // convert legacy\n if (styles && styles.color) {\n styles.fill = styles.color;\n }\n\n // Filter out existing styles to increase performance (#2640)\n if (oldStyles) {\n objectEach(styles, function(style, n) {\n if (style !== oldStyles[n]) {\n newStyles[n] = style;\n hasNew = true;\n }\n });\n }\n if (hasNew) {\n\n // Merge the new styles with the old ones\n if (oldStyles) {\n styles = extend(\n oldStyles,\n newStyles\n );\n }\n\n // Get the text width from style\n textWidth = this.textWidth = (\n styles &&\n styles.width &&\n styles.width !== 'auto' &&\n elem.nodeName.toLowerCase() === 'text' &&\n pInt(styles.width)\n );\n\n // store object\n this.styles = styles;\n\n if (textWidth && (!svg && this.renderer.forExport)) {\n delete styles.width;\n }\n\n // serialize and set style attribute\n if (isMS && !svg) {\n css(this.element, styles);\n } else {\n hyphenate = function(a, b) {\n return '-' + b.toLowerCase();\n };\n objectEach(styles, function(style, n) {\n if (inArray(n, svgPseudoProps) === -1) {\n serializedCss +=\n n.replace(/([A-Z])/g, hyphenate) + ':' +\n style + ';';\n }\n });\n if (serializedCss) {\n attr(elem, 'style', serializedCss); // #1881\n }\n }\n\n\n if (this.added) {\n\n // Rebuild text after added. Cache mechanisms in the buildText\n // will prevent building if there are no significant changes.\n if (this.element.nodeName === 'text') {\n this.renderer.buildText(this);\n }\n\n // Apply text outline after added\n if (styles && styles.textOutline) {\n this.applyTextOutline(styles.textOutline);\n }\n }\n }\n\n return this;\n },\n\n\n /**\n * Get the current stroke width. In classic mode, the setter registers it \n * directly on the element.\n * @returns {number} The stroke width in pixels.\n * @ignore\n */\n strokeWidth: function() {\n return this['stroke-width'] || 0;\n },\n\n\n /**\n * Add an event listener. This is a simple setter that replaces all other\n * events of the same type, opposed to the {@link Highcharts#addEvent}\n * function.\n * @param {string} eventType - The event type. If the type is `click`, \n * Highcharts will internally translate it to a `touchstart` event on \n * touch devices, to prevent the browser from waiting for a click event\n * from firing.\n * @param {Function} handler - The handler callback.\n * @returns {Highcharts.SVGElement} The SVGElement for chaining.\n *\n * @sample highcharts/members/element-on/\n * A clickable rectangle\n */\n on: function(eventType, handler) {\n var svgElement = this,\n element = svgElement.element;\n\n // touch\n if (hasTouch && eventType === 'click') {\n element.ontouchstart = function(e) {\n svgElement.touchEventFired = Date.now(); // #2269\n e.preventDefault();\n handler.call(element, e);\n };\n element.onclick = function(e) {\n if (win.navigator.userAgent.indexOf('Android') === -1 ||\n Date.now() - (svgElement.touchEventFired || 0) > 1100) {\n handler.call(element, e);\n }\n };\n } else {\n // simplest possible event model for internal use\n element['on' + eventType] = handler;\n }\n return this;\n },\n\n /**\n * Set the coordinates needed to draw a consistent radial gradient across\n * a shape regardless of positioning inside the chart. Used on pie slices\n * to make all the slices have the same radial reference point.\n *\n * @param {Array} coordinates The center reference. The format is\n * `[centerX, centerY, diameter]` in pixels.\n * @returns {Highcharts.SVGElement} Returns the SVGElement for chaining.\n */\n setRadialReference: function(coordinates) {\n var existingGradient = this.renderer.gradients[this.element.gradient];\n\n this.element.radialReference = coordinates;\n\n // On redrawing objects with an existing gradient, the gradient needs\n // to be repositioned (#3801)\n if (existingGradient && existingGradient.radAttr) {\n existingGradient.animate(\n this.renderer.getRadialAttr(\n coordinates,\n existingGradient.radAttr\n )\n );\n }\n\n return this;\n },\n\n /**\n * Move an object and its children by x and y values.\n * \n * @param {number} x - The x value.\n * @param {number} y - The y value.\n */\n translate: function(x, y) {\n return this.attr({\n translateX: x,\n translateY: y\n });\n },\n\n /**\n * Invert a group, rotate and flip. This is used internally on inverted \n * charts, where the points and graphs are drawn as if not inverted, then\n * the series group elements are inverted.\n *\n * @param {boolean} inverted - Whether to invert or not. An inverted shape\n * can be un-inverted by setting it to false.\n * @returns {Highcharts.SVGElement} Return the SVGElement for chaining.\n */\n invert: function(inverted) {\n var wrapper = this;\n wrapper.inverted = inverted;\n wrapper.updateTransform();\n return wrapper;\n },\n\n /**\n * Update the transform attribute based on internal properties. Deals with\n * the custom `translateX`, `translateY`, `rotation`, `scaleX` and `scaleY`\n * attributes and updates the SVG `transform` attribute.\n * @private\n * @returns {void}\n */\n updateTransform: function() {\n var wrapper = this,\n translateX = wrapper.translateX || 0,\n translateY = wrapper.translateY || 0,\n scaleX = wrapper.scaleX,\n scaleY = wrapper.scaleY,\n inverted = wrapper.inverted,\n rotation = wrapper.rotation,\n element = wrapper.element,\n transform;\n\n // flipping affects translate as adjustment for flipping around the group's axis\n if (inverted) {\n translateX += wrapper.width;\n translateY += wrapper.height;\n }\n\n // Apply translate. Nearly all transformed elements have translation, so instead\n // of checking for translate = 0, do it always (#1767, #1846).\n transform = ['translate(' + translateX + ',' + translateY + ')'];\n\n // apply rotation\n if (inverted) {\n transform.push('rotate(90) scale(-1,1)');\n } else if (rotation) { // text rotation\n transform.push('rotate(' + rotation + ' ' + (element.getAttribute('x') || 0) + ' ' + (element.getAttribute('y') || 0) + ')');\n\n // Delete bBox memo when the rotation changes\n //delete wrapper.bBox;\n }\n\n // apply scale\n if (defined(scaleX) || defined(scaleY)) {\n transform.push('scale(' + pick(scaleX, 1) + ' ' + pick(scaleY, 1) + ')');\n }\n\n if (transform.length) {\n element.setAttribute('transform', transform.join(' '));\n }\n },\n\n /**\n * Bring the element to the front. Alternatively, a new zIndex can be set.\n *\n * @returns {Highcharts.SVGElement} Returns the SVGElement for chaining.\n *\n * @sample highcharts/members/element-tofront/\n * Click an element to bring it to front\n */\n toFront: function() {\n var element = this.element;\n element.parentNode.appendChild(element);\n return this;\n },\n\n\n /**\n * Align the element relative to the chart or another box.\n * \n * @param {Object} [alignOptions] The alignment options. The function can be\n * called without this parameter in order to re-align an element after the\n * box has been updated.\n * @param {string} [alignOptions.align=left] Horizontal alignment. Can be\n * one of `left`, `center` and `right`.\n * @param {string} [alignOptions.verticalAlign=top] Vertical alignment. Can\n * be one of `top`, `middle` and `bottom`.\n * @param {number} [alignOptions.x=0] Horizontal pixel offset from\n * alignment.\n * @param {number} [alignOptions.y=0] Vertical pixel offset from alignment.\n * @param {Boolean} [alignByTranslate=false] Use the `transform` attribute\n * with translateX and translateY custom attributes to align this elements\n * rather than `x` and `y` attributes.\n * @param {String|Object} box The box to align to, needs a width and height.\n * When the box is a string, it refers to an object in the Renderer. For\n * example, when box is `spacingBox`, it refers to `Renderer.spacingBox`\n * which holds `width`, `height`, `x` and `y` properties.\n * @returns {Highcharts.SVGElement} Returns the SVGElement for chaining.\n */\n align: function(alignOptions, alignByTranslate, box) {\n var align,\n vAlign,\n x,\n y,\n attribs = {},\n alignTo,\n renderer = this.renderer,\n alignedObjects = renderer.alignedObjects,\n alignFactor,\n vAlignFactor;\n\n // First call on instanciate\n if (alignOptions) {\n this.alignOptions = alignOptions;\n this.alignByTranslate = alignByTranslate;\n if (!box || isString(box)) { // boxes other than renderer handle this internally\n this.alignTo = alignTo = box || 'renderer';\n erase(alignedObjects, this); // prevent duplicates, like legendGroup after resize\n alignedObjects.push(this);\n box = null; // reassign it below\n }\n\n // When called on resize, no arguments are supplied\n } else {\n alignOptions = this.alignOptions;\n alignByTranslate = this.alignByTranslate;\n alignTo = this.alignTo;\n }\n\n box = pick(box, renderer[alignTo], renderer);\n\n // Assign variables\n align = alignOptions.align;\n vAlign = alignOptions.verticalAlign;\n x = (box.x || 0) + (alignOptions.x || 0); // default: left align\n y = (box.y || 0) + (alignOptions.y || 0); // default: top align\n\n // Align\n if (align === 'right') {\n alignFactor = 1;\n } else if (align === 'center') {\n alignFactor = 2;\n }\n if (alignFactor) {\n x += (box.width - (alignOptions.width || 0)) / alignFactor;\n }\n attribs[alignByTranslate ? 'translateX' : 'x'] = Math.round(x);\n\n\n // Vertical align\n if (vAlign === 'bottom') {\n vAlignFactor = 1;\n } else if (vAlign === 'middle') {\n vAlignFactor = 2;\n }\n if (vAlignFactor) {\n y += (box.height - (alignOptions.height || 0)) / vAlignFactor;\n }\n attribs[alignByTranslate ? 'translateY' : 'y'] = Math.round(y);\n\n // Animate only if already placed\n this[this.placed ? 'animate' : 'attr'](attribs);\n this.placed = true;\n this.alignAttr = attribs;\n\n return this;\n },\n\n /**\n * Get the bounding box (width, height, x and y) for the element. Generally\n * used to get rendered text size. Since this is called a lot in charts,\n * the results are cached based on text properties, in order to save DOM\n * traffic. The returned bounding box includes the rotation, so for example\n * a single text line of rotation 90 will report a greater height, and a\n * width corresponding to the line-height.\n *\n * @param {boolean} [reload] Skip the cache and get the updated DOM bouding\n * box.\n * @param {number} [rot] Override the element's rotation. This is internally\n * used on axis labels with a value of 0 to find out what the bounding box\n * would be have been if it were not rotated.\n * @returns {Object} The bounding box with `x`, `y`, `width` and `height`\n * properties.\n *\n * @sample highcharts/members/renderer-on-chart/\n * Draw a rectangle based on a text's bounding box\n */\n getBBox: function(reload, rot) {\n var wrapper = this,\n bBox, // = wrapper.bBox,\n renderer = wrapper.renderer,\n width,\n height,\n rotation,\n rad,\n element = wrapper.element,\n styles = wrapper.styles,\n fontSize,\n textStr = wrapper.textStr,\n toggleTextShadowShim,\n cache = renderer.cache,\n cacheKeys = renderer.cacheKeys,\n cacheKey;\n\n rotation = pick(rot, wrapper.rotation);\n rad = rotation * deg2rad;\n\n\n fontSize = styles && styles.fontSize;\n\n\n if (textStr !== undefined) {\n\n cacheKey = textStr.toString();\n\n // Since numbers are monospaced, and numerical labels appear a lot\n // in a chart, we assume that a label of n characters has the same\n // bounding box as others of the same length. Unless there is inner\n // HTML in the label. In that case, leave the numbers as is (#5899).\n if (cacheKey.indexOf('<') === -1) {\n cacheKey = cacheKey.replace(/[0-9]/g, '0');\n }\n\n // Properties that affect bounding box\n cacheKey += [\n '',\n rotation || 0,\n fontSize,\n styles && styles.width,\n styles && styles.textOverflow // #5968\n ]\n .join(',');\n\n }\n\n if (cacheKey && !reload) {\n bBox = cache[cacheKey];\n }\n\n // No cache found\n if (!bBox) {\n\n // SVG elements\n if (element.namespaceURI === wrapper.SVG_NS || renderer.forExport) {\n try { // Fails in Firefox if the container has display: none.\n\n // When the text shadow shim is used, we need to hide the fake shadows\n // to get the correct bounding box (#3872)\n toggleTextShadowShim = this.fakeTS && function(display) {\n each(element.querySelectorAll('.highcharts-text-outline'), function(tspan) {\n tspan.style.display = display;\n });\n };\n\n // Workaround for #3842, Firefox reporting wrong bounding box for shadows\n if (toggleTextShadowShim) {\n toggleTextShadowShim('none');\n }\n\n bBox = element.getBBox ?\n // SVG: use extend because IE9 is not allowed to change width and height in case\n // of rotation (below)\n extend({}, element.getBBox()) : {\n\n // Legacy IE in export mode\n width: element.offsetWidth,\n height: element.offsetHeight\n };\n\n // #3842\n if (toggleTextShadowShim) {\n toggleTextShadowShim('');\n }\n } catch (e) {}\n\n // If the bBox is not set, the try-catch block above failed. The other condition\n // is for Opera that returns a width of -Infinity on hidden elements.\n if (!bBox || bBox.width < 0) {\n bBox = {\n width: 0,\n height: 0\n };\n }\n\n\n // VML Renderer or useHTML within SVG\n } else {\n\n bBox = wrapper.htmlGetBBox();\n\n }\n\n // True SVG elements as well as HTML elements in modern browsers using the .useHTML option\n // need to compensated for rotation\n if (renderer.isSVG) {\n width = bBox.width;\n height = bBox.height;\n\n // Workaround for wrong bounding box in IE, Edge and Chrome on\n // Windows. With Highcharts' default font, IE and Edge report\n // a box height of 16.899 and Chrome rounds it to 17. If this \n // stands uncorrected, it results in more padding added below\n // the text than above when adding a label border or background.\n // Also vertical positioning is affected.\n // http://jsfiddle.net/highcharts/em37nvuj/\n // (#1101, #1505, #1669, #2568, #6213).\n if (\n styles &&\n styles.fontSize === '11px' &&\n Math.round(height) === 17\n ) {\n bBox.height = height = 14;\n }\n\n // Adjust for rotated text\n if (rotation) {\n bBox.width = Math.abs(height * Math.sin(rad)) + Math.abs(width * Math.cos(rad));\n bBox.height = Math.abs(height * Math.cos(rad)) + Math.abs(width * Math.sin(rad));\n }\n }\n\n // Cache it. When loading a chart in a hidden iframe in Firefox and IE/Edge, the\n // bounding box height is 0, so don't cache it (#5620).\n if (cacheKey && bBox.height > 0) {\n\n // Rotate (#4681)\n while (cacheKeys.length > 250) {\n delete cache[cacheKeys.shift()];\n }\n\n if (!cache[cacheKey]) {\n cacheKeys.push(cacheKey);\n }\n cache[cacheKey] = bBox;\n }\n }\n return bBox;\n },\n\n /**\n * Show the element after it has been hidden. \n *\n * @param {boolean} [inherit=false] Set the visibility attribute to\n * `inherit` rather than `visible`. The difference is that an element with\n * `visibility=\"visible\"` will be visible even if the parent is hidden.\n *\n * @returns {Highcharts.SVGElement} Returns the SVGElement for chaining.\n */\n show: function(inherit) {\n return this.attr({\n visibility: inherit ? 'inherit' : 'visible'\n });\n },\n\n /**\n * Hide the element, equivalent to setting the `visibility` attribute to\n * `hidden`.\n *\n * @returns {Highcharts.SVGElement} Returns the SVGElement for chaining.\n */\n hide: function() {\n return this.attr({\n visibility: 'hidden'\n });\n },\n\n /**\n * Fade out an element by animating its opacity down to 0, and hide it on\n * complete. Used internally for the tooltip.\n * \n * @param {number} [duration=150] The fade duration in milliseconds.\n */\n fadeOut: function(duration) {\n var elemWrapper = this;\n elemWrapper.animate({\n opacity: 0\n }, {\n duration: duration || 150,\n complete: function() {\n elemWrapper.attr({\n y: -9999\n }); // #3088, assuming we're only using this for tooltips\n }\n });\n },\n\n /**\n * Add the element to the DOM. All elements must be added this way.\n * \n * @param {Highcharts.SVGElement|SVGDOMElement} [parent] The parent item to add it to.\n * If undefined, the element is added to the {@link\n * Highcharts.SVGRenderer.box}.\n *\n * @returns {Highcharts.SVGElement} Returns the SVGElement for chaining.\n *\n * @sample highcharts/members/renderer-g - Elements added to a group\n */\n add: function(parent) {\n\n var renderer = this.renderer,\n element = this.element,\n inserted;\n\n if (parent) {\n this.parentGroup = parent;\n }\n\n // mark as inverted\n this.parentInverted = parent && parent.inverted;\n\n // build formatted text\n if (this.textStr !== undefined) {\n renderer.buildText(this);\n }\n\n // Mark as added\n this.added = true;\n\n // If we're adding to renderer root, or other elements in the group\n // have a z index, we need to handle it\n if (!parent || parent.handleZ || this.zIndex) {\n inserted = this.zIndexSetter();\n }\n\n // If zIndex is not handled, append at the end\n if (!inserted) {\n (parent ? parent.element : renderer.box).appendChild(element);\n }\n\n // fire an event for internal hooks\n if (this.onAdd) {\n this.onAdd();\n }\n\n return this;\n },\n\n /**\n * Removes an element from the DOM.\n *\n * @private\n * @param {SVGDOMElement|HTMLDOMElement} element The DOM node to remove.\n */\n safeRemoveChild: function(element) {\n var parentNode = element.parentNode;\n if (parentNode) {\n parentNode.removeChild(element);\n }\n },\n\n /**\n * Destroy the element and element wrapper and clear up the DOM and event\n * hooks.\n *\n * @returns {void}\n */\n destroy: function() {\n var wrapper = this,\n element = wrapper.element || {},\n parentToClean =\n wrapper.renderer.isSVG &&\n element.nodeName === 'SPAN' &&\n wrapper.parentGroup,\n grandParent,\n ownerSVGElement = element.ownerSVGElement,\n i;\n\n // remove events\n element.onclick = element.onmouseout = element.onmouseover =\n element.onmousemove = element.point = null;\n stop(wrapper); // stop running animations\n\n if (wrapper.clipPath && ownerSVGElement) {\n // Look for existing references to this clipPath and remove them\n // before destroying the element (#6196).\n each(\n ownerSVGElement.querySelectorAll('[clip-path]'),\n function(el) {\n // Include the closing paranthesis in the test to rule out\n // id's from 10 and above (#6550)\n if (el.getAttribute('clip-path')\n .indexOf(wrapper.clipPath.element.id + ')') > -1) {\n el.removeAttribute('clip-path');\n }\n }\n );\n wrapper.clipPath = wrapper.clipPath.destroy();\n }\n\n // Destroy stops in case this is a gradient object\n if (wrapper.stops) {\n for (i = 0; i < wrapper.stops.length; i++) {\n wrapper.stops[i] = wrapper.stops[i].destroy();\n }\n wrapper.stops = null;\n }\n\n // remove element\n wrapper.safeRemoveChild(element);\n\n\n wrapper.destroyShadows();\n\n\n // In case of useHTML, clean up empty containers emulating SVG groups (#1960, #2393, #2697).\n while (parentToClean && parentToClean.div && parentToClean.div.childNodes.length === 0) {\n grandParent = parentToClean.parentGroup;\n wrapper.safeRemoveChild(parentToClean.div);\n delete parentToClean.div;\n parentToClean = grandParent;\n }\n\n // remove from alignObjects\n if (wrapper.alignTo) {\n erase(wrapper.renderer.alignedObjects, wrapper);\n }\n\n objectEach(wrapper, function(val, key) {\n delete wrapper[key];\n });\n\n return null;\n },\n\n\n /**\n * @typedef {Object} ShadowOptions\n * @property {string} [color=#000000] The shadow color.\n * @property {number} [offsetX=1] The horizontal offset from the element.\n * @property {number} [offsetY=1] The vertical offset from the element.\n * @property {number} [opacity=0.15] The shadow opacity.\n * @property {number} [width=3] The shadow width or distance from the\n * element.\n */\n /**\n * Add a shadow to the element. Must be called after the element is added to\n * the DOM. In styled mode, this method is not used, instead use `defs` and\n * filters.\n * \n * @param {boolean|ShadowOptions} shadowOptions The shadow options. If\n * `true`, the default options are applied. If `false`, the current\n * shadow will be removed.\n * @param {Highcharts.SVGElement} [group] The SVG group element where the shadows will \n * be applied. The default is to add it to the same parent as the current\n * element. Internally, this is ised for pie slices, where all the\n * shadows are added to an element behind all the slices.\n * @param {boolean} [cutOff] Used internally for column shadows.\n *\n * @returns {Highcharts.SVGElement} Returns the SVGElement for chaining.\n *\n * @example\n * renderer.rect(10, 100, 100, 100)\n * .attr({ fill: 'red' })\n * .shadow(true);\n */\n shadow: function(shadowOptions, group, cutOff) {\n var shadows = [],\n i,\n shadow,\n element = this.element,\n strokeWidth,\n shadowWidth,\n shadowElementOpacity,\n\n // compensate for inverted plot area\n transform;\n\n if (!shadowOptions) {\n this.destroyShadows();\n\n } else if (!this.shadows) {\n shadowWidth = pick(shadowOptions.width, 3);\n shadowElementOpacity = (shadowOptions.opacity || 0.15) / shadowWidth;\n transform = this.parentInverted ?\n '(-1,-1)' :\n '(' + pick(shadowOptions.offsetX, 1) + ', ' + pick(shadowOptions.offsetY, 1) + ')';\n for (i = 1; i <= shadowWidth; i++) {\n shadow = element.cloneNode(0);\n strokeWidth = (shadowWidth * 2) + 1 - (2 * i);\n attr(shadow, {\n 'isShadow': 'true',\n 'stroke': shadowOptions.color || '#000000',\n 'stroke-opacity': shadowElementOpacity * i,\n 'stroke-width': strokeWidth,\n 'transform': 'translate' + transform,\n 'fill': 'none'\n });\n if (cutOff) {\n attr(shadow, 'height', Math.max(attr(shadow, 'height') - strokeWidth, 0));\n shadow.cutHeight = strokeWidth;\n }\n\n if (group) {\n group.element.appendChild(shadow);\n } else {\n element.parentNode.insertBefore(shadow, element);\n }\n\n shadows.push(shadow);\n }\n\n this.shadows = shadows;\n }\n return this;\n\n },\n\n /**\n * Destroy shadows on the element.\n * @private\n */\n destroyShadows: function() {\n each(this.shadows || [], function(shadow) {\n this.safeRemoveChild(shadow);\n }, this);\n this.shadows = undefined;\n },\n\n\n\n xGetter: function(key) {\n if (this.element.nodeName === 'circle') {\n if (key === 'x') {\n key = 'cx';\n } else if (key === 'y') {\n key = 'cy';\n }\n }\n return this._defaultGetter(key);\n },\n\n /**\n * Get the current value of an attribute or pseudo attribute, used mainly\n * for animation. Called internally from the {@link\n * Highcharts.SVGRenderer#attr}\n * function.\n *\n * @private\n */\n _defaultGetter: function(key) {\n var ret = pick(this[key], this.element ? this.element.getAttribute(key) : null, 0);\n\n if (/^[\\-0-9\\.]+$/.test(ret)) { // is numerical\n ret = parseFloat(ret);\n }\n return ret;\n },\n\n\n dSetter: function(value, key, element) {\n if (value && value.join) { // join path\n value = value.join(' ');\n }\n if (/(NaN| {2}|^$)/.test(value)) {\n value = 'M 0 0';\n }\n element.setAttribute(key, value);\n\n this[key] = value;\n },\n\n dashstyleSetter: function(value) {\n var i,\n strokeWidth = this['stroke-width'];\n\n // If \"inherit\", like maps in IE, assume 1 (#4981). With HC5 and the new strokeWidth \n // function, we should be able to use that instead.\n if (strokeWidth === 'inherit') {\n strokeWidth = 1;\n }\n value = value && value.toLowerCase();\n if (value) {\n value = value\n .replace('shortdashdotdot', '3,1,1,1,1,1,')\n .replace('shortdashdot', '3,1,1,1')\n .replace('shortdot', '1,1,')\n .replace('shortdash', '3,1,')\n .replace('longdash', '8,3,')\n .replace(/dot/g, '1,3,')\n .replace('dash', '4,3,')\n .replace(/,$/, '')\n .split(','); // ending comma\n\n i = value.length;\n while (i--) {\n value[i] = pInt(value[i]) * strokeWidth;\n }\n value = value.join(',')\n .replace(/NaN/g, 'none'); // #3226\n this.element.setAttribute('stroke-dasharray', value);\n }\n },\n\n alignSetter: function(value) {\n var convert = {\n left: 'start',\n center: 'middle',\n right: 'end'\n };\n this.element.setAttribute('text-anchor', convert[value]);\n },\n opacitySetter: function(value, key, element) {\n this[key] = value;\n element.setAttribute(key, value);\n },\n titleSetter: function(value) {\n var titleNode = this.element.getElementsByTagName('title')[0];\n if (!titleNode) {\n titleNode = doc.createElementNS(this.SVG_NS, 'title');\n this.element.appendChild(titleNode);\n }\n\n // Remove text content if it exists\n if (titleNode.firstChild) {\n titleNode.removeChild(titleNode.firstChild);\n }\n\n titleNode.appendChild(\n doc.createTextNode(\n (String(pick(value), '')).replace(/<[^>]*>/g, '') // #3276, #3895\n )\n );\n },\n textSetter: function(value) {\n if (value !== this.textStr) {\n // Delete bBox memo when the text changes\n delete this.bBox;\n\n this.textStr = value;\n if (this.added) {\n this.renderer.buildText(this);\n }\n }\n },\n fillSetter: function(value, key, element) {\n if (typeof value === 'string') {\n element.setAttribute(key, value);\n } else if (value) {\n this.colorGradient(value, key, element);\n }\n },\n visibilitySetter: function(value, key, element) {\n // IE9-11 doesn't handle visibilty:inherit well, so we remove the attribute instead (#2881, #3909)\n if (value === 'inherit') {\n element.removeAttribute(key);\n } else {\n element.setAttribute(key, value);\n }\n },\n zIndexSetter: function(value, key) {\n var renderer = this.renderer,\n parentGroup = this.parentGroup,\n parentWrapper = parentGroup || renderer,\n parentNode = parentWrapper.element || renderer.box,\n childNodes,\n otherElement,\n otherZIndex,\n element = this.element,\n inserted,\n run = this.added,\n i;\n\n if (defined(value)) {\n element.zIndex = value; // So we can read it for other elements in the group\n value = +value;\n if (this[key] === value) { // Only update when needed (#3865)\n run = false;\n }\n this[key] = value;\n }\n\n // Insert according to this and other elements' zIndex. Before .add() is called,\n // nothing is done. Then on add, or by later calls to zIndexSetter, the node\n // is placed on the right place in the DOM.\n if (run) {\n value = this.zIndex;\n\n if (value && parentGroup) {\n parentGroup.handleZ = true;\n }\n\n childNodes = parentNode.childNodes;\n for (i = 0; i < childNodes.length && !inserted; i++) {\n otherElement = childNodes[i];\n otherZIndex = otherElement.zIndex;\n if (otherElement !== element && (\n // Insert before the first element with a higher zIndex\n pInt(otherZIndex) > value ||\n // If no zIndex given, insert before the first element with a zIndex\n (!defined(value) && defined(otherZIndex)) ||\n // Negative zIndex versus no zIndex:\n // On all levels except the highest. If the parent is ,\n // then we don't want to put items before or \n (value < 0 && !defined(otherZIndex) && parentNode !== renderer.box)\n\n )) {\n parentNode.insertBefore(element, otherElement);\n inserted = true;\n }\n }\n if (!inserted) {\n parentNode.appendChild(element);\n }\n }\n return inserted;\n },\n _defaultSetter: function(value, key, element) {\n element.setAttribute(key, value);\n }\n });\n\n // Some shared setters and getters\n SVGElement.prototype.yGetter = SVGElement.prototype.xGetter;\n SVGElement.prototype.translateXSetter = SVGElement.prototype.translateYSetter =\n SVGElement.prototype.rotationSetter = SVGElement.prototype.verticalAlignSetter =\n SVGElement.prototype.scaleXSetter = SVGElement.prototype.scaleYSetter = function(value, key) {\n this[key] = value;\n this.doTransform = true;\n };\n\n\n // WebKit and Batik have problems with a stroke-width of zero, so in this case we remove the \n // stroke attribute altogether. #1270, #1369, #3065, #3072.\n SVGElement.prototype['stroke-widthSetter'] = SVGElement.prototype.strokeSetter = function(value, key, element) {\n this[key] = value;\n // Only apply the stroke attribute if the stroke width is defined and larger than 0\n if (this.stroke && this['stroke-width']) {\n SVGElement.prototype.fillSetter.call(this, this.stroke, 'stroke', element); // use prototype as instance may be overridden\n element.setAttribute('stroke-width', this['stroke-width']);\n this.hasStroke = true;\n } else if (key === 'stroke-width' && value === 0 && this.hasStroke) {\n element.removeAttribute('stroke');\n this.hasStroke = false;\n }\n };\n\n\n /**\n * Allows direct access to the Highcharts rendering layer in order to draw\n * primitive shapes like circles, rectangles, paths or text directly on a chart,\n * or independent from any chart. The SVGRenderer represents a wrapper object\n * for SVGin modern browsers and through the VMLRenderer, for VML in IE < 8.\n *\n * An existing chart's renderer can be accessed through {@link Chart#renderer}.\n * The renderer can also be used completely decoupled from a chart.\n *\n * @param {HTMLDOMElement} container - Where to put the SVG in the web page.\n * @param {number} width - The width of the SVG.\n * @param {number} height - The height of the SVG.\n * @param {boolean} [forExport=false] - Whether the rendered content is intended\n * for export.\n * @param {boolean} [allowHTML=true] - Whether the renderer is allowed to\n * include HTML text, which will be projected on top of the SVG.\n *\n * @example\n * // Use directly without a chart object.\n * var renderer = new Highcharts.Renderer(parentNode, 600, 400);\n *\n * @sample highcharts/members/renderer-on-chart - Annotating a chart programmatically.\n * @sample highcharts/members/renderer-basic - Independedt SVG drawing.\n *\n * @class Highcharts.SVGRenderer\n */\n SVGRenderer = H.SVGRenderer = function() {\n this.init.apply(this, arguments);\n };\n extend(SVGRenderer.prototype, /** @lends Highcharts.SVGRenderer.prototype */ {\n /**\n * A pointer to the renderer's associated Element class. The VMLRenderer\n * will have a pointer to VMLElement here.\n * @type {Highcharts.SVGElement}\n */\n Element: SVGElement,\n SVG_NS: SVG_NS,\n /**\n * Initialize the SVGRenderer. Overridable initiator function that takes\n * the same parameters as the constructor.\n */\n init: function(container, width, height, style, forExport, allowHTML) {\n var renderer = this,\n boxWrapper,\n element,\n desc;\n\n boxWrapper = renderer.createElement('svg')\n .attr({\n 'version': '1.1',\n 'class': 'highcharts-root'\n })\n\n .css(this.getStyle(style));\n element = boxWrapper.element;\n container.appendChild(element);\n\n // For browsers other than IE, add the namespace attribute (#1978)\n if (container.innerHTML.indexOf('xmlns') === -1) {\n attr(element, 'xmlns', this.SVG_NS);\n }\n\n // object properties\n renderer.isSVG = true;\n\n /** \n * The root `svg` node of the renderer.\n * @type {SVGDOMElement}\n */\n this.box = element;\n /** \n * The wrapper for the root `svg` node of the renderer.\n * @type {Highcharts.SVGElement}\n */\n this.boxWrapper = boxWrapper;\n renderer.alignedObjects = [];\n\n /**\n * Page url used for internal references.\n * @type {string}\n */\n // #24, #672, #1070\n this.url = (isFirefox || isWebKit) && doc.getElementsByTagName('base').length ?\n win.location.href\n .replace(/#.*?$/, '') // remove the hash\n .replace(/<[^>]*>/g, '') // wing cut HTML\n .replace(/([\\('\\)])/g, '\\\\$1') // escape parantheses and quotes\n .replace(/ /g, '%20') : // replace spaces (needed for Safari only)\n '';\n\n // Add description\n desc = this.createElement('desc').add();\n desc.element.appendChild(doc.createTextNode('Created with Highcharts 5.0.12'));\n\n\n renderer.defs = this.createElement('defs').add();\n renderer.allowHTML = allowHTML;\n renderer.forExport = forExport;\n renderer.gradients = {}; // Object where gradient SvgElements are stored\n renderer.cache = {}; // Cache for numerical bounding boxes\n renderer.cacheKeys = [];\n renderer.imgCount = 0;\n\n renderer.setSize(width, height, false);\n\n\n\n // Issue 110 workaround:\n // In Firefox, if a div is positioned by percentage, its pixel position may land\n // between pixels. The container itself doesn't display this, but an SVG element\n // inside this container will be drawn at subpixel precision. In order to draw\n // sharp lines, this must be compensated for. This doesn't seem to work inside\n // iframes though (like in jsFiddle).\n var subPixelFix, rect;\n if (isFirefox && container.getBoundingClientRect) {\n subPixelFix = function() {\n css(container, {\n left: 0,\n top: 0\n });\n rect = container.getBoundingClientRect();\n css(container, {\n left: (Math.ceil(rect.left) - rect.left) + 'px',\n top: (Math.ceil(rect.top) - rect.top) + 'px'\n });\n };\n\n // run the fix now\n subPixelFix();\n\n // run it on resize\n renderer.unSubPixelFix = addEvent(win, 'resize', subPixelFix);\n }\n },\n\n\n\n /**\n * Get the global style setting for the renderer.\n * @private\n * @param {CSSObject} style - Style settings.\n * @return {CSSObject} The style settings mixed with defaults.\n */\n getStyle: function(style) {\n this.style = extend({\n\n fontFamily: '\"Lucida Grande\", \"Lucida Sans Unicode\", Arial, Helvetica, sans-serif', // default font\n fontSize: '12px'\n\n }, style);\n return this.style;\n },\n /**\n * Apply the global style on the renderer, mixed with the default styles.\n * @param {CSSObject} style - CSS to apply.\n */\n setStyle: function(style) {\n this.boxWrapper.css(this.getStyle(style));\n },\n\n\n /**\n * Detect whether the renderer is hidden. This happens when one of the\n * parent elements has display: none. Used internally to detect when we need\n * to render preliminarily in another div to get the text bounding boxes \n * right.\n *\n * @returns {boolean} True if it is hidden.\n */\n isHidden: function() { // #608\n return !this.boxWrapper.getBBox().width;\n },\n\n /**\n * Destroys the renderer and its allocated members.\n */\n destroy: function() {\n var renderer = this,\n rendererDefs = renderer.defs;\n renderer.box = null;\n renderer.boxWrapper = renderer.boxWrapper.destroy();\n\n // Call destroy on all gradient elements\n destroyObjectProperties(renderer.gradients || {});\n renderer.gradients = null;\n\n // Defs are null in VMLRenderer\n // Otherwise, destroy them here.\n if (rendererDefs) {\n renderer.defs = rendererDefs.destroy();\n }\n\n // Remove sub pixel fix handler (#982)\n if (renderer.unSubPixelFix) {\n renderer.unSubPixelFix();\n }\n\n renderer.alignedObjects = null;\n\n return null;\n },\n\n /**\n * Create a wrapper for an SVG element. Serves as a factory for \n * {@link SVGElement}, but this function is itself mostly called from \n * primitive factories like {@link SVGRenderer#path}, {@link\n * SVGRenderer#rect} or {@link SVGRenderer#text}.\n * \n * @param {string} nodeName - The node name, for example `rect`, `g` etc.\n * @returns {Highcharts.SVGElement} The generated SVGElement.\n */\n createElement: function(nodeName) {\n var wrapper = new this.Element();\n wrapper.init(this, nodeName);\n return wrapper;\n },\n\n /**\n * Dummy function for plugins, called every time the renderer is updated.\n * Prior to Highcharts 5, this was used for the canvg renderer.\n * @function\n */\n draw: noop,\n\n /**\n * Get converted radial gradient attributes according to the radial\n * reference. Used internally from the {@link SVGElement#colorGradient}\n * function.\n *\n * @private\n */\n getRadialAttr: function(radialReference, gradAttr) {\n return {\n cx: (radialReference[0] - radialReference[2] / 2) + gradAttr.cx * radialReference[2],\n cy: (radialReference[1] - radialReference[2] / 2) + gradAttr.cy * radialReference[2],\n r: gradAttr.r * radialReference[2]\n };\n },\n\n getSpanWidth: function(wrapper, tspan) {\n var renderer = this,\n bBox = wrapper.getBBox(true),\n actualWidth = bBox.width;\n\n // Old IE cannot measure the actualWidth for SVG elements (#2314)\n if (!svg && renderer.forExport) {\n actualWidth = renderer.measureSpanWidth(tspan.firstChild.data, wrapper.styles);\n }\n return actualWidth;\n },\n\n applyEllipsis: function(wrapper, tspan, text, width) {\n var renderer = this,\n actualWidth = renderer.getSpanWidth(wrapper, tspan),\n wasTooLong = actualWidth > width,\n str = text,\n currentIndex,\n minIndex = 0,\n maxIndex = text.length,\n updateTSpan = function(s) {\n tspan.removeChild(tspan.firstChild);\n if (s) {\n tspan.appendChild(doc.createTextNode(s));\n }\n };\n if (wasTooLong) {\n while (minIndex <= maxIndex) {\n currentIndex = Math.ceil((minIndex + maxIndex) / 2);\n str = text.substring(0, currentIndex) + '\\u2026';\n updateTSpan(str);\n actualWidth = renderer.getSpanWidth(wrapper, tspan);\n if (minIndex === maxIndex) {\n // Complete\n minIndex = maxIndex + 1;\n } else if (actualWidth > width) {\n // Too large. Set max index to current.\n maxIndex = currentIndex - 1;\n } else {\n // Within width. Set min index to current.\n minIndex = currentIndex;\n }\n }\n // If max index was 0 it means just ellipsis was also to large.\n if (maxIndex === 0) {\n // Remove ellipses.\n updateTSpan('');\n }\n }\n return wasTooLong;\n },\n\n /**\n * Parse a simple HTML string into SVG tspans. Called internally when text\n * is set on an SVGElement. The function supports a subset of HTML tags,\n * CSS text features like `width`, `text-overflow`, `white-space`, and\n * also attributes like `href` and `style`.\n * @private\n * @param {Highcharts.SVGElement} wrapper The parent SVGElement.\n */\n buildText: function(wrapper) {\n var textNode = wrapper.element,\n renderer = this,\n forExport = renderer.forExport,\n textStr = pick(wrapper.textStr, '').toString(),\n hasMarkup = textStr.indexOf('<') !== -1,\n lines,\n childNodes = textNode.childNodes,\n clsRegex,\n styleRegex,\n hrefRegex,\n wasTooLong,\n parentX = attr(textNode, 'x'),\n textStyles = wrapper.styles,\n width = wrapper.textWidth,\n textLineHeight = textStyles && textStyles.lineHeight,\n textOutline = textStyles && textStyles.textOutline,\n ellipsis = textStyles && textStyles.textOverflow === 'ellipsis',\n noWrap = textStyles && textStyles.whiteSpace === 'nowrap',\n fontSize = textStyles && textStyles.fontSize,\n textCache,\n isSubsequentLine,\n i = childNodes.length,\n tempParent = width && !wrapper.added && this.box,\n getLineHeight = function(tspan) {\n var fontSizeStyle;\n\n fontSizeStyle = /(px|em)$/.test(tspan && tspan.style.fontSize) ?\n tspan.style.fontSize :\n (fontSize || renderer.style.fontSize || 12);\n\n\n return textLineHeight ?\n pInt(textLineHeight) :\n renderer.fontMetrics(\n fontSizeStyle,\n // Get the computed size from parent if not explicit\n tspan.getAttribute('style') ? tspan : textNode\n ).h;\n },\n unescapeAngleBrackets = function(inputStr) {\n return inputStr.replace(/</g, '<').replace(/>/g, '>');\n };\n\n // The buildText code is quite heavy, so if we're not changing something\n // that affects the text, skip it (#6113).\n textCache = [\n textStr,\n ellipsis,\n noWrap,\n textLineHeight,\n textOutline,\n fontSize,\n width\n ].join(',');\n if (textCache === wrapper.textCache) {\n return;\n }\n wrapper.textCache = textCache;\n\n /// remove old text\n while (i--) {\n textNode.removeChild(childNodes[i]);\n }\n\n // Skip tspans, add text directly to text node. The forceTSpan is a hook\n // used in text outline hack.\n if (!hasMarkup && !textOutline && !ellipsis && !width && textStr.indexOf(' ') === -1) {\n textNode.appendChild(doc.createTextNode(unescapeAngleBrackets(textStr)));\n\n // Complex strings, add more logic\n } else {\n\n clsRegex = /<.*class=\"([^\"]+)\".*>/;\n styleRegex = /<.*style=\"([^\"]+)\".*>/;\n hrefRegex = /<.*href=\"([^\"]+)\".*>/;\n\n if (tempParent) {\n tempParent.appendChild(textNode); // attach it to the DOM to read offset width\n }\n\n if (hasMarkup) {\n lines = textStr\n\n .replace(/<(b|strong)>/g, '')\n .replace(/<(i|em)>/g, '')\n\n .replace(//g, '')\n .split(//g);\n\n } else {\n lines = [textStr];\n }\n\n\n // Trim empty lines (#5261)\n lines = grep(lines, function(line) {\n return line !== '';\n });\n\n\n // build the lines\n each(lines, function buildTextLines(line, lineNo) {\n var spans,\n spanNo = 0;\n line = line\n .replace(/^\\s+|\\s+$/g, '') // Trim to prevent useless/costly process on the spaces (#5258)\n .replace(//g, '|||');\n spans = line.split('|||');\n\n each(spans, function buildTextSpans(span) {\n if (span !== '' || spans.length === 1) {\n var attributes = {},\n tspan = doc.createElementNS(renderer.SVG_NS, 'tspan'),\n spanCls,\n spanStyle; // #390\n if (clsRegex.test(span)) {\n spanCls = span.match(clsRegex)[1];\n attr(tspan, 'class', spanCls);\n }\n if (styleRegex.test(span)) {\n spanStyle = span.match(styleRegex)[1].replace(/(;| |^)color([ :])/, '$1fill$2');\n attr(tspan, 'style', spanStyle);\n }\n if (hrefRegex.test(span) && !forExport) { // Not for export - #1529\n attr(tspan, 'onclick', 'location.href=\\\"' + span.match(hrefRegex)[1] + '\\\"');\n css(tspan, {\n cursor: 'pointer'\n });\n }\n\n span = unescapeAngleBrackets(span.replace(/<(.|\\n)*?>/g, '') || ' ');\n\n // Nested tags aren't supported, and cause crash in Safari (#1596)\n if (span !== ' ') {\n\n // add the text node\n tspan.appendChild(doc.createTextNode(span));\n\n if (!spanNo) { // first span in a line, align it to the left\n if (lineNo && parentX !== null) {\n attributes.x = parentX;\n }\n } else {\n attributes.dx = 0; // #16\n }\n\n // add attributes\n attr(tspan, attributes);\n\n // Append it\n textNode.appendChild(tspan);\n\n // first span on subsequent line, add the line height\n if (!spanNo && isSubsequentLine) {\n\n // allow getting the right offset height in exporting in IE\n if (!svg && forExport) {\n css(tspan, {\n display: 'block'\n });\n }\n\n // Set the line height based on the font size of either\n // the text element or the tspan element\n attr(\n tspan,\n 'dy',\n getLineHeight(tspan)\n );\n }\n\n /*if (width) {\n renderer.breakText(wrapper, width);\n }*/\n\n // Check width and apply soft breaks or ellipsis\n if (width) {\n var words = span.replace(/([^\\^])-/g, '$1- ').split(' '), // #1273\n hasWhiteSpace = spans.length > 1 || lineNo || (words.length > 1 && !noWrap),\n tooLong,\n rest = [],\n actualWidth,\n dy = getLineHeight(tspan),\n rotation = wrapper.rotation;\n\n if (ellipsis) {\n wasTooLong = renderer.applyEllipsis(wrapper, tspan, span, width);\n }\n\n while (!ellipsis && hasWhiteSpace && (words.length || rest.length)) {\n wrapper.rotation = 0; // discard rotation when computing box\n actualWidth = renderer.getSpanWidth(wrapper, tspan);\n tooLong = actualWidth > width;\n\n // For ellipsis, do a binary search for the correct string length\n if (wasTooLong === undefined) {\n wasTooLong = tooLong; // First time\n }\n\n // Looping down, this is the first word sequence that is not too long,\n // so we can move on to build the next line.\n if (!tooLong || words.length === 1) {\n words = rest;\n rest = [];\n\n if (words.length && !noWrap) {\n tspan = doc.createElementNS(SVG_NS, 'tspan');\n attr(tspan, {\n dy: dy,\n x: parentX\n });\n if (spanStyle) { // #390\n attr(tspan, 'style', spanStyle);\n }\n textNode.appendChild(tspan);\n }\n if (actualWidth > width) { // a single word is pressing it out\n width = actualWidth;\n }\n } else { // append to existing line tspan\n tspan.removeChild(tspan.firstChild);\n rest.unshift(words.pop());\n }\n if (words.length) {\n tspan.appendChild(doc.createTextNode(words.join(' ').replace(/- /g, '-')));\n }\n }\n wrapper.rotation = rotation;\n }\n\n spanNo++;\n }\n }\n });\n // To avoid beginning lines that doesn't add to the textNode (#6144)\n isSubsequentLine = isSubsequentLine || textNode.childNodes.length;\n });\n\n if (wasTooLong) {\n wrapper.attr('title', wrapper.textStr);\n }\n if (tempParent) {\n tempParent.removeChild(textNode); // attach it to the DOM to read offset width\n }\n\n // Apply the text outline\n if (textOutline && wrapper.applyTextOutline) {\n wrapper.applyTextOutline(textOutline);\n }\n }\n },\n\n\n\n /*\n breakText: function (wrapper, width) {\n var bBox = wrapper.getBBox(),\n node = wrapper.element,\n textLength = node.textContent.length,\n pos = Math.round(width * textLength / bBox.width), // try this position first, based on average character width\n increment = 0,\n finalPos;\n\n if (bBox.width > width) {\n while (finalPos === undefined) {\n textLength = node.getSubStringLength(0, pos);\n\n if (textLength <= width) {\n if (increment === -1) {\n finalPos = pos;\n } else {\n increment = 1;\n }\n } else {\n if (increment === 1) {\n finalPos = pos - 1;\n } else {\n increment = -1;\n }\n }\n pos += increment;\n }\n }\n console.log('width', width, 'stringWidth', node.getSubStringLength(0, finalPos))\n },\n */\n\n /**\n * Returns white for dark colors and black for bright colors.\n *\n * @param {ColorString} rgba - The color to get the contrast for.\n * @returns {string} The contrast color, either `#000000` or `#FFFFFF`.\n */\n getContrast: function(rgba) {\n rgba = color(rgba).rgba;\n\n // The threshold may be discussed. Here's a proposal for adding\n // different weight to the color channels (#6216)\n /*\n rgba[0] *= 1; // red\n rgba[1] *= 1.2; // green\n rgba[2] *= 0.7; // blue\n */\n\n return rgba[0] + rgba[1] + rgba[2] > 2 * 255 ? '#000000' : '#FFFFFF';\n },\n\n /**\n * Create a button with preset states.\n * @param {string} text - The text or HTML to draw.\n * @param {number} x - The x position of the button's left side.\n * @param {number} y - The y position of the button's top side.\n * @param {Function} callback - The function to execute on button click or \n * touch.\n * @param {SVGAttributes} [normalState] - SVG attributes for the normal\n * state.\n * @param {SVGAttributes} [hoverState] - SVG attributes for the hover state.\n * @param {SVGAttributes} [pressedState] - SVG attributes for the pressed\n * state.\n * @param {SVGAttributes} [disabledState] - SVG attributes for the disabled\n * state.\n * @param {Symbol} [shape=rect] - The shape type.\n * @returns {SVGRenderer} The button element.\n */\n button: function(text, x, y, callback, normalState, hoverState, pressedState, disabledState, shape) {\n var label = this.label(text, x, y, shape, null, null, null, null, 'button'),\n curState = 0;\n\n // Default, non-stylable attributes\n label.attr(merge({\n 'padding': 8,\n 'r': 2\n }, normalState));\n\n\n // Presentational\n var normalStyle,\n hoverStyle,\n pressedStyle,\n disabledStyle;\n\n // Normal state - prepare the attributes\n normalState = merge({\n fill: '#f7f7f7',\n stroke: '#cccccc',\n 'stroke-width': 1,\n style: {\n color: '#333333',\n cursor: 'pointer',\n fontWeight: 'normal'\n }\n }, normalState);\n normalStyle = normalState.style;\n delete normalState.style;\n\n // Hover state\n hoverState = merge(normalState, {\n fill: '#e6e6e6'\n }, hoverState);\n hoverStyle = hoverState.style;\n delete hoverState.style;\n\n // Pressed state\n pressedState = merge(normalState, {\n fill: '#e6ebf5',\n style: {\n color: '#000000',\n fontWeight: 'bold'\n }\n }, pressedState);\n pressedStyle = pressedState.style;\n delete pressedState.style;\n\n // Disabled state\n disabledState = merge(normalState, {\n style: {\n color: '#cccccc'\n }\n }, disabledState);\n disabledStyle = disabledState.style;\n delete disabledState.style;\n\n\n // Add the events. IE9 and IE10 need mouseover and mouseout to funciton (#667).\n addEvent(label.element, isMS ? 'mouseover' : 'mouseenter', function() {\n if (curState !== 3) {\n label.setState(1);\n }\n });\n addEvent(label.element, isMS ? 'mouseout' : 'mouseleave', function() {\n if (curState !== 3) {\n label.setState(curState);\n }\n });\n\n label.setState = function(state) {\n // Hover state is temporary, don't record it\n if (state !== 1) {\n label.state = curState = state;\n }\n // Update visuals\n label.removeClass(/highcharts-button-(normal|hover|pressed|disabled)/)\n .addClass('highcharts-button-' + ['normal', 'hover', 'pressed', 'disabled'][state || 0]);\n\n\n label.attr([normalState, hoverState, pressedState, disabledState][state || 0])\n .css([normalStyle, hoverStyle, pressedStyle, disabledStyle][state || 0]);\n\n };\n\n\n\n // Presentational attributes\n label\n .attr(normalState)\n .css(extend({\n cursor: 'default'\n }, normalStyle));\n\n\n return label\n .on('click', function(e) {\n if (curState !== 3) {\n callback.call(label, e);\n }\n });\n },\n\n /**\n * Make a straight line crisper by not spilling out to neighbour pixels.\n * \n * @param {Array} points - The original points on the format `['M', 0, 0,\n * 'L', 100, 0]`.\n * @param {number} width - The width of the line.\n * @returns {Array} The original points array, but modified to render\n * crisply.\n */\n crispLine: function(points, width) {\n // normalize to a crisp line\n if (points[1] === points[4]) {\n // Substract due to #1129. Now bottom and left axis gridlines behave the same.\n points[1] = points[4] = Math.round(points[1]) - (width % 2 / 2);\n }\n if (points[2] === points[5]) {\n points[2] = points[5] = Math.round(points[2]) + (width % 2 / 2);\n }\n return points;\n },\n\n\n /**\n * Draw a path, wraps the SVG `path` element.\n * \n * @param {Array} [path] An SVG path definition in array form.\n * \n * @example\n * var path = renderer.path(['M', 10, 10, 'L', 30, 30, 'z'])\n * .attr({ stroke: '#ff00ff' })\n * .add();\n * @returns {Highcharts.SVGElement} The generated wrapper element.\n *\n * @sample highcharts/members/renderer-path-on-chart/\n * Draw a path in a chart\n * @sample highcharts/members/renderer-path/\n * Draw a path independent from a chart\n *\n */\n /**\n * Draw a path, wraps the SVG `path` element.\n * \n * @param {SVGAttributes} [attribs] The initial attributes.\n * @returns {Highcharts.SVGElement} The generated wrapper element.\n */\n path: function(path) {\n var attribs = {\n\n fill: 'none'\n\n };\n if (isArray(path)) {\n attribs.d = path;\n } else if (isObject(path)) { // attributes\n extend(attribs, path);\n }\n return this.createElement('path').attr(attribs);\n },\n\n /**\n * Draw a circle, wraps the SVG `circle` element.\n * \n * @param {number} [x] The center x position.\n * @param {number} [y] The center y position.\n * @param {number} [r] The radius.\n * @returns {Highcharts.SVGElement} The generated wrapper element.\n *\n * @sample highcharts/members/renderer-circle/ Drawing a circle\n */\n /**\n * Draw a circle, wraps the SVG `circle` element.\n * \n * @param {SVGAttributes} [attribs] The initial attributes.\n * @returns {Highcharts.SVGElement} The generated wrapper element.\n */\n circle: function(x, y, r) {\n var attribs = isObject(x) ? x : {\n x: x,\n y: y,\n r: r\n },\n wrapper = this.createElement('circle');\n\n // Setting x or y translates to cx and cy\n wrapper.xSetter = wrapper.ySetter = function(value, key, element) {\n element.setAttribute('c' + key, value);\n };\n\n return wrapper.attr(attribs);\n },\n\n /**\n * Draw and return an arc.\n * @param {number} [x=0] Center X position.\n * @param {number} [y=0] Center Y position.\n * @param {number} [r=0] The outer radius of the arc.\n * @param {number} [innerR=0] Inner radius like used in donut charts.\n * @param {number} [start=0] The starting angle of the arc in radians, where\n * 0 is to the right and `-Math.PI/2` is up.\n * @param {number} [end=0] The ending angle of the arc in radians, where 0\n * is to the right and `-Math.PI/2` is up.\n * @returns {Highcharts.SVGElement} The generated wrapper element.\n *\n * @sample highcharts/members/renderer-arc/\n * Drawing an arc\n */\n /**\n * Draw and return an arc. Overloaded function that takes arguments object.\n * @param {SVGAttributes} attribs Initial SVG attributes.\n * @returns {Highcharts.SVGElement} The generated wrapper element.\n */\n arc: function(x, y, r, innerR, start, end) {\n var arc,\n options;\n\n if (isObject(x)) {\n options = x;\n y = options.y;\n r = options.r;\n innerR = options.innerR;\n start = options.start;\n end = options.end;\n x = options.x;\n } else {\n options = {\n innerR: innerR,\n start: start,\n end: end\n };\n }\n\n // Arcs are defined as symbols for the ability to set\n // attributes in attr and animate\n arc = this.symbol('arc', x, y, r, r, options);\n arc.r = r; // #959\n return arc;\n },\n\n /**\n * Draw and return a rectangle.\n * @param {number} [x] Left position.\n * @param {number} [y] Top position.\n * @param {number} [width] Width of the rectangle.\n * @param {number} [height] Height of the rectangle.\n * @param {number} [r] Border corner radius.\n * @param {number} [strokeWidth] A stroke width can be supplied to allow\n * crisp drawing.\n * @returns {Highcharts.SVGElement} The generated wrapper element.\n */\n /**\n * Draw and return a rectangle.\n * @param {SVGAttributes} [attributes]\n * General SVG attributes for the rectangle.\n * @return {Highcharts.SVGElement}\n * The generated wrapper element.\n *\n * @sample highcharts/members/renderer-rect-on-chart/\n * Draw a rectangle in a chart\n * @sample highcharts/members/renderer-rect/\n * Draw a rectangle independent from a chart\n */\n rect: function(x, y, width, height, r, strokeWidth) {\n\n r = isObject(x) ? x.r : r;\n\n var wrapper = this.createElement('rect'),\n attribs = isObject(x) ? x : x === undefined ? {} : {\n x: x,\n y: y,\n width: Math.max(width, 0),\n height: Math.max(height, 0)\n };\n\n\n if (strokeWidth !== undefined) {\n attribs.strokeWidth = strokeWidth;\n attribs = wrapper.crisp(attribs);\n }\n attribs.fill = 'none';\n\n\n if (r) {\n attribs.r = r;\n }\n\n wrapper.rSetter = function(value, key, element) {\n attr(element, {\n rx: value,\n ry: value\n });\n };\n\n return wrapper.attr(attribs);\n },\n\n /**\n * Resize the {@link SVGRenderer#box} and re-align all aligned child\n * elements.\n * @param {number} width The new pixel width.\n * @param {number} height The new pixel height.\n * @param {boolean} animate Whether to animate.\n */\n setSize: function(width, height, animate) {\n var renderer = this,\n alignedObjects = renderer.alignedObjects,\n i = alignedObjects.length;\n\n renderer.width = width;\n renderer.height = height;\n\n renderer.boxWrapper.animate({\n width: width,\n height: height\n }, {\n step: function() {\n this.attr({\n viewBox: '0 0 ' + this.attr('width') + ' ' + this.attr('height')\n });\n },\n duration: pick(animate, true) ? undefined : 0\n });\n\n while (i--) {\n alignedObjects[i].align();\n }\n },\n\n /**\n * Create and return an svg group element. Child {@link Highcharts.SVGElement}\n * objects are added to the group by using the group as the first parameter\n * in {@link Highcharts.SVGElement#add|add()}.\n * \n * @param {string} [name] The group will be given a class name of\n * `highcharts-{name}`. This can be used for styling and scripting.\n * @returns {Highcharts.SVGElement} The generated wrapper element.\n *\n * @sample highcharts/members/renderer-g/\n * Show and hide grouped objects\n */\n g: function(name) {\n var elem = this.createElement('g');\n return name ? elem.attr({\n 'class': 'highcharts-' + name\n }) : elem;\n },\n\n /**\n * Display an image.\n * @param {string} src The image source.\n * @param {number} [x] The X position.\n * @param {number} [y] The Y position.\n * @param {number} [width] The image width. If omitted, it defaults to the \n * image file width.\n * @param {number} [height] The image height. If omitted it defaults to the\n * image file height.\n * @returns {Highcharts.SVGElement} The generated wrapper element.\n *\n * @sample highcharts/members/renderer-image-on-chart/\n * Add an image in a chart\n * @sample highcharts/members/renderer-image/\n * Add an image independent of a chart\n */\n image: function(src, x, y, width, height) {\n var attribs = {\n preserveAspectRatio: 'none'\n },\n elemWrapper;\n\n // optional properties\n if (arguments.length > 1) {\n extend(attribs, {\n x: x,\n y: y,\n width: width,\n height: height\n });\n }\n\n elemWrapper = this.createElement('image').attr(attribs);\n\n // set the href in the xlink namespace\n if (elemWrapper.element.setAttributeNS) {\n elemWrapper.element.setAttributeNS('http://www.w3.org/1999/xlink',\n 'href', src);\n } else {\n // could be exporting in IE\n // using href throws \"not supported\" in ie7 and under, requries regex shim to fix later\n elemWrapper.element.setAttribute('hc-svg-href', src);\n }\n return elemWrapper;\n },\n\n /**\n * Draw a symbol out of pre-defined shape paths from {@SVGRenderer#symbols}.\n * It is used in Highcharts for point makers, which cake a `symbol` option,\n * and label and button backgrounds like in the tooltip and stock flags.\n *\n * @param {Symbol} symbol - The symbol name.\n * @param {number} x - The X coordinate for the top left position.\n * @param {number} y - The Y coordinate for the top left position.\n * @param {number} width - The pixel width.\n * @param {number} height - The pixel height.\n * @param {Object} [options] - Additional options, depending on the actual\n * symbol drawn. \n * @param {number} [options.anchorX] - The anchor X position for the\n * `callout` symbol. This is where the chevron points to.\n * @param {number} [options.anchorY] - The anchor Y position for the\n * `callout` symbol. This is where the chevron points to.\n * @param {number} [options.end] - The end angle of an `arc` symbol.\n * @param {boolean} [options.open] - Whether to draw `arc` symbol open or\n * closed.\n * @param {number} [options.r] - The radius of an `arc` symbol, or the\n * border radius for the `callout` symbol.\n * @param {number} [options.start] - The start angle of an `arc` symbol.\n */\n symbol: function(symbol, x, y, width, height, options) {\n\n var ren = this,\n obj,\n imageRegex = /^url\\((.*?)\\)$/,\n isImage = imageRegex.test(symbol),\n sym = !isImage && (this.symbols[symbol] ? symbol : 'circle'),\n\n\n // get the symbol definition function\n symbolFn = sym && this.symbols[sym],\n\n // check if there's a path defined for this symbol\n path = defined(x) && symbolFn && symbolFn.call(\n this.symbols,\n Math.round(x),\n Math.round(y),\n width,\n height,\n options\n ),\n imageSrc,\n centerImage;\n\n if (symbolFn) {\n obj = this.path(path);\n\n\n obj.attr('fill', 'none');\n\n\n // expando properties for use in animate and attr\n extend(obj, {\n symbolName: sym,\n x: x,\n y: y,\n width: width,\n height: height\n });\n if (options) {\n extend(obj, options);\n }\n\n\n // Image symbols\n } else if (isImage) {\n\n\n imageSrc = symbol.match(imageRegex)[1];\n\n // Create the image synchronously, add attribs async\n obj = this.image(imageSrc);\n\n // The image width is not always the same as the symbol width. The\n // image may be centered within the symbol, as is the case when\n // image shapes are used as label backgrounds, for example in flags.\n obj.imgwidth = pick(\n symbolSizes[imageSrc] && symbolSizes[imageSrc].width,\n options && options.width\n );\n obj.imgheight = pick(\n symbolSizes[imageSrc] && symbolSizes[imageSrc].height,\n options && options.height\n );\n /**\n * Set the size and position\n */\n centerImage = function() {\n obj.attr({\n width: obj.width,\n height: obj.height\n });\n };\n\n /**\n * Width and height setters that take both the image's physical size\n * and the label size into consideration, and translates the image\n * to center within the label.\n */\n each(['width', 'height'], function(key) {\n obj[key + 'Setter'] = function(value, key) {\n var attribs = {},\n imgSize = this['img' + key],\n trans = key === 'width' ? 'translateX' : 'translateY';\n this[key] = value;\n if (defined(imgSize)) {\n if (this.element) {\n this.element.setAttribute(key, imgSize);\n }\n if (!this.alignByTranslate) {\n attribs[trans] = ((this[key] || 0) - imgSize) / 2;\n this.attr(attribs);\n }\n }\n };\n });\n\n\n if (defined(x)) {\n obj.attr({\n x: x,\n y: y\n });\n }\n obj.isImg = true;\n\n if (defined(obj.imgwidth) && defined(obj.imgheight)) {\n centerImage();\n } else {\n // Initialize image to be 0 size so export will still function if there's no cached sizes.\n obj.attr({\n width: 0,\n height: 0\n });\n\n // Create a dummy JavaScript image to get the width and height. Due to a bug in IE < 8,\n // the created element must be assigned to a variable in order to load (#292).\n createElement('img', {\n onload: function() {\n\n var chart = charts[ren.chartIndex];\n\n // Special case for SVGs on IE11, the width is not accessible until the image is\n // part of the DOM (#2854).\n if (this.width === 0) {\n css(this, {\n position: 'absolute',\n top: '-999em'\n });\n doc.body.appendChild(this);\n }\n\n // Center the image\n symbolSizes[imageSrc] = { // Cache for next \n width: this.width,\n height: this.height\n };\n obj.imgwidth = this.width;\n obj.imgheight = this.height;\n\n if (obj.element) {\n centerImage();\n }\n\n // Clean up after #2854 workaround.\n if (this.parentNode) {\n this.parentNode.removeChild(this);\n }\n\n // Fire the load event when all external images are loaded\n ren.imgCount--;\n if (!ren.imgCount && chart && chart.onload) {\n chart.onload();\n }\n },\n src: imageSrc\n });\n this.imgCount++;\n }\n }\n\n return obj;\n },\n\n /**\n * @typedef {string} Symbol\n * \n * Can be one of `arc`, `callout`, `circle`, `diamond`, `square`,\n * `triangle`, `triangle-down`. Symbols are used internally for point\n * markers, button and label borders and backgrounds, or custom shapes.\n * Extendable by adding to {@link SVGRenderer#symbols}.\n */\n /**\n * An extendable collection of functions for defining symbol paths.\n */\n symbols: {\n 'circle': function(x, y, w, h) {\n // Return a full arc\n return this.arc(x + w / 2, y + h / 2, w / 2, h / 2, {\n start: 0,\n end: Math.PI * 2,\n open: false\n });\n },\n\n 'square': function(x, y, w, h) {\n return [\n 'M', x, y,\n 'L', x + w, y,\n x + w, y + h,\n x, y + h,\n 'Z'\n ];\n },\n\n 'triangle': function(x, y, w, h) {\n return [\n 'M', x + w / 2, y,\n 'L', x + w, y + h,\n x, y + h,\n 'Z'\n ];\n },\n\n 'triangle-down': function(x, y, w, h) {\n return [\n 'M', x, y,\n 'L', x + w, y,\n x + w / 2, y + h,\n 'Z'\n ];\n },\n 'diamond': function(x, y, w, h) {\n return [\n 'M', x + w / 2, y,\n 'L', x + w, y + h / 2,\n x + w / 2, y + h,\n x, y + h / 2,\n 'Z'\n ];\n },\n 'arc': function(x, y, w, h, options) {\n var start = options.start,\n rx = options.r || w,\n ry = options.r || h || w,\n end = options.end - 0.001, // to prevent cos and sin of start and end from becoming equal on 360 arcs (related: #1561)\n innerRadius = options.innerR,\n open = options.open,\n cosStart = Math.cos(start),\n sinStart = Math.sin(start),\n cosEnd = Math.cos(end),\n sinEnd = Math.sin(end),\n longArc = options.end - start < Math.PI ? 0 : 1,\n arc;\n\n arc = [\n 'M',\n x + rx * cosStart,\n y + ry * sinStart,\n 'A', // arcTo\n rx, // x radius\n ry, // y radius\n 0, // slanting\n longArc, // long or short arc\n 1, // clockwise\n x + rx * cosEnd,\n y + ry * sinEnd\n ];\n\n if (defined(innerRadius)) {\n arc.push(\n open ? 'M' : 'L',\n x + innerRadius * cosEnd,\n y + innerRadius * sinEnd,\n 'A', // arcTo\n innerRadius, // x radius\n innerRadius, // y radius\n 0, // slanting\n longArc, // long or short arc\n 0, // clockwise\n x + innerRadius * cosStart,\n y + innerRadius * sinStart\n );\n }\n\n arc.push(open ? '' : 'Z'); // close\n return arc;\n },\n\n /**\n * Callout shape used for default tooltips, also used for rounded rectangles in VML\n */\n callout: function(x, y, w, h, options) {\n var arrowLength = 6,\n halfDistance = 6,\n r = Math.min((options && options.r) || 0, w, h),\n safeDistance = r + halfDistance,\n anchorX = options && options.anchorX,\n anchorY = options && options.anchorY,\n path;\n\n path = [\n 'M', x + r, y,\n 'L', x + w - r, y, // top side\n 'C', x + w, y, x + w, y, x + w, y + r, // top-right corner\n 'L', x + w, y + h - r, // right side\n 'C', x + w, y + h, x + w, y + h, x + w - r, y + h, // bottom-right corner\n 'L', x + r, y + h, // bottom side\n 'C', x, y + h, x, y + h, x, y + h - r, // bottom-left corner\n 'L', x, y + r, // left side\n 'C', x, y, x, y, x + r, y // top-left corner\n ];\n\n // Anchor on right side\n if (anchorX && anchorX > w) {\n\n // Chevron\n if (anchorY > y + safeDistance && anchorY < y + h - safeDistance) {\n path.splice(13, 3,\n 'L', x + w, anchorY - halfDistance,\n x + w + arrowLength, anchorY,\n x + w, anchorY + halfDistance,\n x + w, y + h - r\n );\n\n // Simple connector\n } else {\n path.splice(13, 3,\n 'L', x + w, h / 2,\n anchorX, anchorY,\n x + w, h / 2,\n x + w, y + h - r\n );\n }\n\n // Anchor on left side\n } else if (anchorX && anchorX < 0) {\n\n // Chevron\n if (anchorY > y + safeDistance && anchorY < y + h - safeDistance) {\n path.splice(33, 3,\n 'L', x, anchorY + halfDistance,\n x - arrowLength, anchorY,\n x, anchorY - halfDistance,\n x, y + r\n );\n\n // Simple connector\n } else {\n path.splice(33, 3,\n 'L', x, h / 2,\n anchorX, anchorY,\n x, h / 2,\n x, y + r\n );\n }\n\n } else if (anchorY && anchorY > h && anchorX > x + safeDistance && anchorX < x + w - safeDistance) { // replace bottom\n path.splice(23, 3,\n 'L', anchorX + halfDistance, y + h,\n anchorX, y + h + arrowLength,\n anchorX - halfDistance, y + h,\n x + r, y + h\n );\n } else if (anchorY && anchorY < 0 && anchorX > x + safeDistance && anchorX < x + w - safeDistance) { // replace top\n path.splice(3, 3,\n 'L', anchorX - halfDistance, y,\n anchorX, y - arrowLength,\n anchorX + halfDistance, y,\n w - r, y\n );\n }\n\n return path;\n }\n },\n\n /**\n * @typedef {Highcharts.SVGElement} ClipRect - A clipping rectangle that can be applied\n * to one or more {@link SVGElement} instances. It is instanciated with the\n * {@link SVGRenderer#clipRect} function and applied with the {@link \n * SVGElement#clip} function.\n *\n * @example\n * var circle = renderer.circle(100, 100, 100)\n * .attr({ fill: 'red' })\n * .add();\n * var clipRect = renderer.clipRect(100, 100, 100, 100);\n *\n * // Leave only the lower right quarter visible\n * circle.clip(clipRect);\n */\n /**\n * Define a clipping rectangle\n * @param {String} id\n * @param {number} x\n * @param {number} y\n * @param {number} width\n * @param {number} height\n * @returns {ClipRect} A clipping rectangle.\n */\n clipRect: function(x, y, width, height) {\n var wrapper,\n id = H.uniqueKey(),\n\n clipPath = this.createElement('clipPath').attr({\n id: id\n }).add(this.defs);\n\n wrapper = this.rect(x, y, width, height, 0).add(clipPath);\n wrapper.id = id;\n wrapper.clipPath = clipPath;\n wrapper.count = 0;\n\n return wrapper;\n },\n\n\n\n\n\n /**\n * Draw text. The text can contain a subset of HTML, like spans and anchors\n * and some basic text styling of these. For more advanced features like\n * border and background, use {@link Highcharts.SVGRenderer#label} instead.\n * To update the text after render, run `text.attr({ text: 'New text' })`.\n * @param {String} str\n * The text of (subset) HTML to draw.\n * @param {number} x\n * The x position of the text's lower left corner.\n * @param {number} y\n * The y position of the text's lower left corner.\n * @param {Boolean} [useHTML=false]\n * Use HTML to render the text.\n *\n * @return {Highcharts.SVGElement} The text object.\n *\n * @sample highcharts/members/renderer-text-on-chart/\n * Annotate the chart freely\n * @sample highcharts/members/renderer-on-chart/\n * Annotate with a border and in response to the data\n * @sample highcharts/members/renderer-text/\n * Formatted text\n */\n text: function(str, x, y, useHTML) {\n\n // declare variables\n var renderer = this,\n fakeSVG = !svg && renderer.forExport,\n wrapper,\n attribs = {};\n\n if (useHTML && (renderer.allowHTML || !renderer.forExport)) {\n return renderer.html(str, x, y);\n }\n\n attribs.x = Math.round(x || 0); // X is always needed for line-wrap logic\n if (y) {\n attribs.y = Math.round(y);\n }\n if (str || str === 0) {\n attribs.text = str;\n }\n\n wrapper = renderer.createElement('text')\n .attr(attribs);\n\n // Prevent wrapping from creating false offsetWidths in export in legacy IE (#1079, #1063)\n if (fakeSVG) {\n wrapper.css({\n position: 'absolute'\n });\n }\n\n if (!useHTML) {\n wrapper.xSetter = function(value, key, element) {\n var tspans = element.getElementsByTagName('tspan'),\n tspan,\n parentVal = element.getAttribute(key),\n i;\n for (i = 0; i < tspans.length; i++) {\n tspan = tspans[i];\n // If the x values are equal, the tspan represents a linebreak\n if (tspan.getAttribute(key) === parentVal) {\n tspan.setAttribute(key, value);\n }\n }\n element.setAttribute(key, value);\n };\n }\n\n return wrapper;\n },\n\n /**\n * Utility to return the baseline offset and total line height from the font\n * size.\n *\n * @param {?string} fontSize The current font size to inspect. If not given,\n * the font size will be found from the DOM element.\n * @param {SVGElement|SVGDOMElement} [elem] The element to inspect for a\n * current font size.\n * @returns {Object} An object containing `h`: the line height, `b`: the\n * baseline relative to the top of the box, and `f`: the font size.\n */\n fontMetrics: function(fontSize, elem) {\n var lineHeight,\n baseline;\n\n\n fontSize = fontSize ||\n // When the elem is a DOM element (#5932)\n (elem && elem.style && elem.style.fontSize) ||\n // Fall back on the renderer style default\n (this.style && this.style.fontSize);\n\n\n\n // Handle different units\n if (/px/.test(fontSize)) {\n fontSize = pInt(fontSize);\n } else if (/em/.test(fontSize)) {\n // The em unit depends on parent items\n fontSize = parseFloat(fontSize) *\n (elem ? this.fontMetrics(null, elem.parentNode).f : 16);\n } else {\n fontSize = 12;\n }\n\n // Empirical values found by comparing font size and bounding box\n // height. Applies to the default font family.\n // http://jsfiddle.net/highcharts/7xvn7/\n lineHeight = fontSize < 24 ? fontSize + 3 : Math.round(fontSize * 1.2);\n baseline = Math.round(lineHeight * 0.8);\n\n return {\n h: lineHeight,\n b: baseline,\n f: fontSize\n };\n },\n\n /**\n * Correct X and Y positioning of a label for rotation (#1764)\n */\n rotCorr: function(baseline, rotation, alterY) {\n var y = baseline;\n if (rotation && alterY) {\n y = Math.max(y * Math.cos(rotation * deg2rad), 4);\n }\n return {\n x: (-baseline / 3) * Math.sin(rotation * deg2rad),\n y: y\n };\n },\n\n /**\n * Draw a label, which is an extended text element with support for border\n * and background. Highcharts creates a `g` element with a text and a `path`\n * or `rect` inside, to make it behave somewhat like a HTML div. Border and\n * background are set through `stroke`, `stroke-width` and `fill` attributes\n * using the {@link Highcharts.SVGElement#attr|attr} method. To update the\n * text after render, run `label.attr({ text: 'New text' })`.\n * \n * @param {string} str\n * The initial text string or (subset) HTML to render.\n * @param {number} x\n * The x position of the label's left side.\n * @param {number} y\n * The y position of the label's top side or baseline, depending on\n * the `baseline` parameter.\n * @param {String} shape\n * The shape of the label's border/background, if any. Defaults to\n * `rect`. Other possible values are `callout` or other shapes\n * defined in {@link Highcharts.SVGRenderer#symbols}.\n * @param {number} anchorX\n * In case the `shape` has a pointer, like a flag, this is the\n * coordinates it should be pinned to.\n * @param {number} anchorY\n * In case the `shape` has a pointer, like a flag, this is the\n * coordinates it should be pinned to.\n * @param {Boolean} baseline\n * Whether to position the label relative to the text baseline,\n * like {@link Highcharts.SVGRenderer#text|renderer.text}, or to the\n * upper border of the rectangle.\n * @param {String} className\n * Class name for the group.\n *\n * @return {Highcharts.SVGElement}\n * The generated label.\n *\n * @sample highcharts/members/renderer-label-on-chart/\n * A label on the chart\n */\n label: function(str, x, y, shape, anchorX, anchorY, useHTML, baseline, className) {\n\n var renderer = this,\n wrapper = renderer.g(className !== 'button' && 'label'),\n text = wrapper.text = renderer.text('', 0, 0, useHTML)\n .attr({\n zIndex: 1\n }),\n box,\n bBox,\n alignFactor = 0,\n padding = 3,\n paddingLeft = 0,\n width,\n height,\n wrapperX,\n wrapperY,\n textAlign,\n deferredAttr = {},\n strokeWidth,\n baselineOffset,\n hasBGImage = /^url\\((.*?)\\)$/.test(shape),\n needsBox = hasBGImage,\n getCrispAdjust,\n updateBoxSize,\n updateTextPadding,\n boxAttr;\n\n if (className) {\n wrapper.addClass('highcharts-' + className);\n }\n\n\n needsBox = hasBGImage;\n getCrispAdjust = function() {\n return (strokeWidth || 0) % 2 / 2;\n };\n\n\n\n /**\n * This function runs after the label is added to the DOM (when the bounding box is\n * available), and after the text of the label is updated to detect the new bounding\n * box and reflect it in the border box.\n */\n updateBoxSize = function() {\n var style = text.element.style,\n crispAdjust,\n attribs = {};\n\n bBox = (width === undefined || height === undefined || textAlign) && defined(text.textStr) &&\n text.getBBox(); //#3295 && 3514 box failure when string equals 0\n wrapper.width = (width || bBox.width || 0) + 2 * padding + paddingLeft;\n wrapper.height = (height || bBox.height || 0) + 2 * padding;\n\n // Update the label-scoped y offset\n baselineOffset = padding + renderer.fontMetrics(style && style.fontSize, text).b;\n\n\n if (needsBox) {\n\n // Create the border box if it is not already present\n if (!box) {\n wrapper.box = box = renderer.symbols[shape] || hasBGImage ? // Symbol definition exists (#5324)\n renderer.symbol(shape) :\n renderer.rect();\n\n box.addClass(\n (className === 'button' ? '' : 'highcharts-label-box') + // Don't use label className for buttons\n (className ? ' highcharts-' + className + '-box' : '')\n );\n\n box.add(wrapper);\n\n crispAdjust = getCrispAdjust();\n attribs.x = crispAdjust;\n attribs.y = (baseline ? -baselineOffset : 0) + crispAdjust;\n }\n\n // Apply the box attributes\n attribs.width = Math.round(wrapper.width);\n attribs.height = Math.round(wrapper.height);\n\n box.attr(extend(attribs, deferredAttr));\n deferredAttr = {};\n }\n };\n\n /**\n * This function runs after setting text or padding, but only if padding is changed\n */\n updateTextPadding = function() {\n var textX = paddingLeft + padding,\n textY;\n\n // determin y based on the baseline\n textY = baseline ? 0 : baselineOffset;\n\n // compensate for alignment\n if (defined(width) && bBox && (textAlign === 'center' || textAlign === 'right')) {\n textX += {\n center: 0.5,\n right: 1\n }[textAlign] * (width - bBox.width);\n }\n\n // update if anything changed\n if (textX !== text.x || textY !== text.y) {\n text.attr('x', textX);\n if (textY !== undefined) {\n text.attr('y', textY);\n }\n }\n\n // record current values\n text.x = textX;\n text.y = textY;\n };\n\n /**\n * Set a box attribute, or defer it if the box is not yet created\n * @param {Object} key\n * @param {Object} value\n */\n boxAttr = function(key, value) {\n if (box) {\n box.attr(key, value);\n } else {\n deferredAttr[key] = value;\n }\n };\n\n /**\n * After the text element is added, get the desired size of the border box\n * and add it before the text in the DOM.\n */\n wrapper.onAdd = function() {\n text.add(wrapper);\n wrapper.attr({\n text: (str || str === 0) ? str : '', // alignment is available now // #3295: 0 not rendered if given as a value\n x: x,\n y: y\n });\n\n if (box && defined(anchorX)) {\n wrapper.attr({\n anchorX: anchorX,\n anchorY: anchorY\n });\n }\n };\n\n /*\n * Add specific attribute setters.\n */\n\n // only change local variables\n wrapper.widthSetter = function(value) {\n width = H.isNumber(value) ? value : null; // width:auto => null\n };\n wrapper.heightSetter = function(value) {\n height = value;\n };\n wrapper['text-alignSetter'] = function(value) {\n textAlign = value;\n };\n wrapper.paddingSetter = function(value) {\n if (defined(value) && value !== padding) {\n padding = wrapper.padding = value;\n updateTextPadding();\n }\n };\n wrapper.paddingLeftSetter = function(value) {\n if (defined(value) && value !== paddingLeft) {\n paddingLeft = value;\n updateTextPadding();\n }\n };\n\n\n // change local variable and prevent setting attribute on the group\n wrapper.alignSetter = function(value) {\n value = {\n left: 0,\n center: 0.5,\n right: 1\n }[value];\n if (value !== alignFactor) {\n alignFactor = value;\n if (bBox) { // Bounding box exists, means we're dynamically changing\n wrapper.attr({\n x: wrapperX\n }); // #5134\n }\n }\n };\n\n // apply these to the box and the text alike\n wrapper.textSetter = function(value) {\n if (value !== undefined) {\n text.textSetter(value);\n }\n updateBoxSize();\n updateTextPadding();\n };\n\n // apply these to the box but not to the text\n wrapper['stroke-widthSetter'] = function(value, key) {\n if (value) {\n needsBox = true;\n }\n strokeWidth = this['stroke-width'] = value;\n boxAttr(key, value);\n };\n\n wrapper.strokeSetter = wrapper.fillSetter = wrapper.rSetter = function(value, key) {\n if (key === 'fill' && value) {\n needsBox = true;\n }\n boxAttr(key, value);\n };\n\n wrapper.anchorXSetter = function(value, key) {\n anchorX = wrapper.anchorX = value;\n boxAttr(key, Math.round(value) - getCrispAdjust() - wrapperX);\n };\n wrapper.anchorYSetter = function(value, key) {\n anchorY = wrapper.anchorY = value;\n boxAttr(key, value - wrapperY);\n };\n\n // rename attributes\n wrapper.xSetter = function(value) {\n wrapper.x = value; // for animation getter\n if (alignFactor) {\n value -= alignFactor * ((width || bBox.width) + 2 * padding);\n }\n wrapperX = Math.round(value);\n wrapper.attr('translateX', wrapperX);\n };\n wrapper.ySetter = function(value) {\n wrapperY = wrapper.y = Math.round(value);\n wrapper.attr('translateY', wrapperY);\n };\n\n // Redirect certain methods to either the box or the text\n var baseCss = wrapper.css;\n return extend(wrapper, {\n /**\n * Pick up some properties and apply them to the text instead of the\n * wrapper.\n * @ignore\n */\n css: function(styles) {\n if (styles) {\n var textStyles = {};\n styles = merge(styles); // create a copy to avoid altering the original object (#537)\n each(wrapper.textProps, function(prop) {\n if (styles[prop] !== undefined) {\n textStyles[prop] = styles[prop];\n delete styles[prop];\n }\n });\n text.css(textStyles);\n }\n return baseCss.call(wrapper, styles);\n },\n /**\n * Return the bounding box of the box, not the group.\n * @ignore\n */\n getBBox: function() {\n return {\n width: bBox.width + 2 * padding,\n height: bBox.height + 2 * padding,\n x: bBox.x - padding,\n y: bBox.y - padding\n };\n },\n\n /**\n * Apply the shadow to the box.\n * @ignore\n */\n shadow: function(b) {\n if (b) {\n updateBoxSize();\n if (box) {\n box.shadow(b);\n }\n }\n return wrapper;\n },\n\n /**\n * Destroy and release memory.\n * @ignore\n */\n destroy: function() {\n\n // Added by button implementation\n removeEvent(wrapper.element, 'mouseenter');\n removeEvent(wrapper.element, 'mouseleave');\n\n if (text) {\n text = text.destroy();\n }\n if (box) {\n box = box.destroy();\n }\n // Call base implementation to destroy the rest\n SVGElement.prototype.destroy.call(wrapper);\n\n // Release local pointers (#1298)\n wrapper = renderer = updateBoxSize = updateTextPadding = boxAttr = null;\n }\n });\n }\n }); // end SVGRenderer\n\n\n // general renderer\n H.Renderer = SVGRenderer;\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var attr = H.attr,\n createElement = H.createElement,\n css = H.css,\n defined = H.defined,\n each = H.each,\n extend = H.extend,\n isFirefox = H.isFirefox,\n isMS = H.isMS,\n isWebKit = H.isWebKit,\n pInt = H.pInt,\n SVGElement = H.SVGElement,\n SVGRenderer = H.SVGRenderer,\n win = H.win,\n wrap = H.wrap;\n\n // Extend SvgElement for useHTML option\n extend(SVGElement.prototype, /** @lends SVGElement.prototype */ {\n /**\n * Apply CSS to HTML elements. This is used in text within SVG rendering and\n * by the VML renderer\n */\n htmlCss: function(styles) {\n var wrapper = this,\n element = wrapper.element,\n textWidth = styles && element.tagName === 'SPAN' && styles.width;\n\n if (textWidth) {\n delete styles.width;\n wrapper.textWidth = textWidth;\n wrapper.updateTransform();\n }\n if (styles && styles.textOverflow === 'ellipsis') {\n styles.whiteSpace = 'nowrap';\n styles.overflow = 'hidden';\n }\n wrapper.styles = extend(wrapper.styles, styles);\n css(wrapper.element, styles);\n\n return wrapper;\n },\n\n /**\n * VML and useHTML method for calculating the bounding box based on offsets\n * @param {Boolean} refresh Whether to force a fresh value from the DOM or to\n * use the cached value\n *\n * @return {Object} A hash containing values for x, y, width and height\n */\n\n htmlGetBBox: function() {\n var wrapper = this,\n element = wrapper.element;\n\n // faking getBBox in exported SVG in legacy IE\n // faking getBBox in exported SVG in legacy IE (is this a duplicate of the fix for #1079?)\n if (element.nodeName === 'text') {\n element.style.position = 'absolute';\n }\n\n return {\n x: element.offsetLeft,\n y: element.offsetTop,\n width: element.offsetWidth,\n height: element.offsetHeight\n };\n },\n\n /**\n * VML override private method to update elements based on internal\n * properties based on SVG transform\n */\n htmlUpdateTransform: function() {\n // aligning non added elements is expensive\n if (!this.added) {\n this.alignOnAdd = true;\n return;\n }\n\n var wrapper = this,\n renderer = wrapper.renderer,\n elem = wrapper.element,\n translateX = wrapper.translateX || 0,\n translateY = wrapper.translateY || 0,\n x = wrapper.x || 0,\n y = wrapper.y || 0,\n align = wrapper.textAlign || 'left',\n alignCorrection = {\n left: 0,\n center: 0.5,\n right: 1\n }[align],\n styles = wrapper.styles;\n\n // apply translate\n css(elem, {\n marginLeft: translateX,\n marginTop: translateY\n });\n\n\n if (wrapper.shadows) { // used in labels/tooltip\n each(wrapper.shadows, function(shadow) {\n css(shadow, {\n marginLeft: translateX + 1,\n marginTop: translateY + 1\n });\n });\n }\n\n\n // apply inversion\n if (wrapper.inverted) { // wrapper is a group\n each(elem.childNodes, function(child) {\n renderer.invertChild(child, elem);\n });\n }\n\n if (elem.tagName === 'SPAN') {\n\n var rotation = wrapper.rotation,\n baseline,\n textWidth = pInt(wrapper.textWidth),\n whiteSpace = styles && styles.whiteSpace,\n currentTextTransform = [rotation, align, elem.innerHTML, wrapper.textWidth, wrapper.textAlign].join(',');\n\n if (currentTextTransform !== wrapper.cTT) { // do the calculations and DOM access only if properties changed\n\n\n baseline = renderer.fontMetrics(elem.style.fontSize).b;\n\n // Renderer specific handling of span rotation\n if (defined(rotation)) {\n wrapper.setSpanRotation(rotation, alignCorrection, baseline);\n }\n\n // Reset multiline/ellipsis in order to read width (#4928, #5417)\n css(elem, {\n width: '',\n whiteSpace: whiteSpace || 'nowrap'\n });\n\n // Update textWidth\n if (elem.offsetWidth > textWidth && /[ \\-]/.test(elem.textContent || elem.innerText)) { // #983, #1254\n css(elem, {\n width: textWidth + 'px',\n display: 'block',\n whiteSpace: whiteSpace || 'normal' // #3331\n });\n }\n\n\n wrapper.getSpanCorrection(elem.offsetWidth, baseline, alignCorrection, rotation, align);\n }\n\n // apply position with correction\n css(elem, {\n left: (x + (wrapper.xCorr || 0)) + 'px',\n top: (y + (wrapper.yCorr || 0)) + 'px'\n });\n\n // force reflow in webkit to apply the left and top on useHTML element (#1249)\n if (isWebKit) {\n baseline = elem.offsetHeight; // assigned to baseline for lint purpose\n }\n\n // record current text transform\n wrapper.cTT = currentTextTransform;\n }\n },\n\n /**\n * Set the rotation of an individual HTML span\n */\n setSpanRotation: function(rotation, alignCorrection, baseline) {\n var rotationStyle = {},\n cssTransformKey = isMS ? '-ms-transform' : isWebKit ? '-webkit-transform' : isFirefox ? 'MozTransform' : win.opera ? '-o-transform' : '';\n\n rotationStyle[cssTransformKey] = rotationStyle.transform = 'rotate(' + rotation + 'deg)';\n rotationStyle[cssTransformKey + (isFirefox ? 'Origin' : '-origin')] = rotationStyle.transformOrigin = (alignCorrection * 100) + '% ' + baseline + 'px';\n css(this.element, rotationStyle);\n },\n\n /**\n * Get the correction in X and Y positioning as the element is rotated.\n */\n getSpanCorrection: function(width, baseline, alignCorrection) {\n this.xCorr = -width * alignCorrection;\n this.yCorr = -baseline;\n }\n });\n\n // Extend SvgRenderer for useHTML option.\n extend(SVGRenderer.prototype, /** @lends SVGRenderer.prototype */ {\n /**\n * Create HTML text node. This is used by the VML renderer as well as the SVG\n * renderer through the useHTML option.\n *\n * @param {String} str\n * @param {Number} x\n * @param {Number} y\n */\n html: function(str, x, y) {\n var wrapper = this.createElement('span'),\n element = wrapper.element,\n renderer = wrapper.renderer,\n isSVG = renderer.isSVG,\n addSetters = function(element, style) {\n // These properties are set as attributes on the SVG group, and as\n // identical CSS properties on the div. (#3542)\n each(['opacity', 'visibility'], function(prop) {\n wrap(element, prop + 'Setter', function(proceed, value, key, elem) {\n proceed.call(this, value, key, elem);\n style[key] = value;\n });\n });\n };\n\n // Text setter\n wrapper.textSetter = function(value) {\n if (value !== element.innerHTML) {\n delete this.bBox;\n }\n element.innerHTML = this.textStr = value;\n wrapper.htmlUpdateTransform();\n };\n\n // Add setters for the element itself (#4938)\n if (isSVG) { // #4938, only for HTML within SVG\n addSetters(wrapper, wrapper.element.style);\n }\n\n // Various setters which rely on update transform\n wrapper.xSetter = wrapper.ySetter = wrapper.alignSetter = wrapper.rotationSetter = function(value, key) {\n if (key === 'align') {\n key = 'textAlign'; // Do not overwrite the SVGElement.align method. Same as VML.\n }\n wrapper[key] = value;\n wrapper.htmlUpdateTransform();\n };\n\n // Set the default attributes\n wrapper\n .attr({\n text: str,\n x: Math.round(x),\n y: Math.round(y)\n })\n .css({\n\n fontFamily: this.style.fontFamily,\n fontSize: this.style.fontSize,\n\n position: 'absolute'\n });\n\n // Keep the whiteSpace style outside the wrapper.styles collection\n element.style.whiteSpace = 'nowrap';\n\n // Use the HTML specific .css method\n wrapper.css = wrapper.htmlCss;\n\n // This is specific for HTML within SVG\n if (isSVG) {\n wrapper.add = function(svgGroupWrapper) {\n\n var htmlGroup,\n container = renderer.box.parentNode,\n parentGroup,\n parents = [];\n\n this.parentGroup = svgGroupWrapper;\n\n // Create a mock group to hold the HTML elements\n if (svgGroupWrapper) {\n htmlGroup = svgGroupWrapper.div;\n if (!htmlGroup) {\n\n // Read the parent chain into an array and read from top down\n parentGroup = svgGroupWrapper;\n while (parentGroup) {\n\n parents.push(parentGroup);\n\n // Move up to the next parent group\n parentGroup = parentGroup.parentGroup;\n }\n\n // Ensure dynamically updating position when any parent is translated\n each(parents.reverse(), function(parentGroup) {\n var htmlGroupStyle,\n cls = attr(parentGroup.element, 'class');\n\n if (cls) {\n cls = {\n className: cls\n };\n } // else null\n\n // Create a HTML div and append it to the parent div to emulate\n // the SVG group structure\n htmlGroup = parentGroup.div = parentGroup.div || createElement('div', cls, {\n position: 'absolute',\n left: (parentGroup.translateX || 0) + 'px',\n top: (parentGroup.translateY || 0) + 'px',\n display: parentGroup.display,\n opacity: parentGroup.opacity, // #5075\n pointerEvents: parentGroup.styles && parentGroup.styles.pointerEvents // #5595\n }, htmlGroup || container); // the top group is appended to container\n\n // Shortcut\n htmlGroupStyle = htmlGroup.style;\n\n // Set listeners to update the HTML div's position whenever the SVG group\n // position is changed\n extend(parentGroup, {\n on: function() {\n wrapper.on.apply({\n element: parents[0].div\n }, arguments);\n return parentGroup;\n },\n translateXSetter: function(value, key) {\n htmlGroupStyle.left = value + 'px';\n parentGroup[key] = value;\n parentGroup.doTransform = true;\n },\n translateYSetter: function(value, key) {\n htmlGroupStyle.top = value + 'px';\n parentGroup[key] = value;\n parentGroup.doTransform = true;\n }\n });\n addSetters(parentGroup, htmlGroupStyle);\n });\n\n }\n } else {\n htmlGroup = container;\n }\n\n htmlGroup.appendChild(element);\n\n // Shared with VML:\n wrapper.added = true;\n if (wrapper.alignOnAdd) {\n wrapper.htmlUpdateTransform();\n }\n\n return wrapper;\n };\n }\n return wrapper;\n }\n });\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n\n var VMLRenderer,\n VMLRendererExtension,\n VMLElement,\n\n createElement = H.createElement,\n css = H.css,\n defined = H.defined,\n deg2rad = H.deg2rad,\n discardElement = H.discardElement,\n doc = H.doc,\n each = H.each,\n erase = H.erase,\n extend = H.extend,\n extendClass = H.extendClass,\n isArray = H.isArray,\n isNumber = H.isNumber,\n isObject = H.isObject,\n merge = H.merge,\n noop = H.noop,\n pick = H.pick,\n pInt = H.pInt,\n svg = H.svg,\n SVGElement = H.SVGElement,\n SVGRenderer = H.SVGRenderer,\n win = H.win;\n\n /* ****************************************************************************\n * *\n * START OF INTERNET EXPLORER <= 8 SPECIFIC CODE *\n * *\n * For applications and websites that don't need IE support, like platform *\n * targeted mobile apps and web apps, this code can be removed. *\n * *\n *****************************************************************************/\n\n /**\n * @constructor\n */\n if (!svg) {\n\n /**\n * The VML element wrapper.\n */\n VMLElement = {\n\n docMode8: doc && doc.documentMode === 8,\n\n /**\n * Initialize a new VML element wrapper. It builds the markup as a string\n * to minimize DOM traffic.\n * @param {Object} renderer\n * @param {Object} nodeName\n */\n init: function(renderer, nodeName) {\n var wrapper = this,\n markup = ['<', nodeName, ' filled=\"f\" stroked=\"f\"'],\n style = ['position: ', 'absolute', ';'],\n isDiv = nodeName === 'div';\n\n // divs and shapes need size\n if (nodeName === 'shape' || isDiv) {\n style.push('left:0;top:0;width:1px;height:1px;');\n }\n style.push('visibility: ', isDiv ? 'hidden' : 'visible');\n\n markup.push(' style=\"', style.join(''), '\"/>');\n\n // create element with default attributes and style\n if (nodeName) {\n markup = isDiv || nodeName === 'span' || nodeName === 'img' ?\n markup.join('') :\n renderer.prepVML(markup);\n wrapper.element = createElement(markup);\n }\n\n wrapper.renderer = renderer;\n },\n\n /**\n * Add the node to the given parent\n * @param {Object} parent\n */\n add: function(parent) {\n var wrapper = this,\n renderer = wrapper.renderer,\n element = wrapper.element,\n box = renderer.box,\n inverted = parent && parent.inverted,\n\n // get the parent node\n parentNode = parent ?\n parent.element || parent :\n box;\n\n if (parent) {\n this.parentGroup = parent;\n }\n\n // if the parent group is inverted, apply inversion on all children\n if (inverted) { // only on groups\n renderer.invertChild(element, parentNode);\n }\n\n // append it\n parentNode.appendChild(element);\n\n // align text after adding to be able to read offset\n wrapper.added = true;\n if (wrapper.alignOnAdd && !wrapper.deferUpdateTransform) {\n wrapper.updateTransform();\n }\n\n // fire an event for internal hooks\n if (wrapper.onAdd) {\n wrapper.onAdd();\n }\n\n // IE8 Standards can't set the class name before the element is appended\n if (this.className) {\n this.attr('class', this.className);\n }\n\n return wrapper;\n },\n\n /**\n * VML always uses htmlUpdateTransform\n */\n updateTransform: SVGElement.prototype.htmlUpdateTransform,\n\n /**\n * Set the rotation of a span with oldIE's filter\n */\n setSpanRotation: function() {\n // Adjust for alignment and rotation. Rotation of useHTML content is not yet implemented\n // but it can probably be implemented for Firefox 3.5+ on user request. FF3.5+\n // has support for CSS3 transform. The getBBox method also needs to be updated\n // to compensate for the rotation, like it currently does for SVG.\n // Test case: http://jsfiddle.net/highcharts/Ybt44/\n\n var rotation = this.rotation,\n costheta = Math.cos(rotation * deg2rad),\n sintheta = Math.sin(rotation * deg2rad);\n\n css(this.element, {\n filter: rotation ? ['progid:DXImageTransform.Microsoft.Matrix(M11=', costheta,\n ', M12=', -sintheta, ', M21=', sintheta, ', M22=', costheta,\n ', sizingMethod=\\'auto expand\\')'\n ].join('') : 'none'\n });\n },\n\n /**\n * Get the positioning correction for the span after rotating.\n */\n getSpanCorrection: function(width, baseline, alignCorrection, rotation, align) {\n\n var costheta = rotation ? Math.cos(rotation * deg2rad) : 1,\n sintheta = rotation ? Math.sin(rotation * deg2rad) : 0,\n height = pick(this.elemHeight, this.element.offsetHeight),\n quad,\n nonLeft = align && align !== 'left';\n\n // correct x and y\n this.xCorr = costheta < 0 && -width;\n this.yCorr = sintheta < 0 && -height;\n\n // correct for baseline and corners spilling out after rotation\n quad = costheta * sintheta < 0;\n this.xCorr += sintheta * baseline * (quad ? 1 - alignCorrection : alignCorrection);\n this.yCorr -= costheta * baseline * (rotation ? (quad ? alignCorrection : 1 - alignCorrection) : 1);\n // correct for the length/height of the text\n if (nonLeft) {\n this.xCorr -= width * alignCorrection * (costheta < 0 ? -1 : 1);\n if (rotation) {\n this.yCorr -= height * alignCorrection * (sintheta < 0 ? -1 : 1);\n }\n css(this.element, {\n textAlign: align\n });\n }\n },\n\n /**\n * Converts a subset of an SVG path definition to its VML counterpart. Takes an array\n * as the parameter and returns a string.\n */\n pathToVML: function(value) {\n // convert paths\n var i = value.length,\n path = [];\n\n while (i--) {\n\n // Multiply by 10 to allow subpixel precision.\n // Substracting half a pixel seems to make the coordinates\n // align with SVG, but this hasn't been tested thoroughly\n if (isNumber(value[i])) {\n path[i] = Math.round(value[i] * 10) - 5;\n } else if (value[i] === 'Z') { // close the path\n path[i] = 'x';\n } else {\n path[i] = value[i];\n\n // When the start X and end X coordinates of an arc are too close,\n // they are rounded to the same value above. In this case, substract or\n // add 1 from the end X and Y positions. #186, #760, #1371, #1410.\n if (value.isArc && (value[i] === 'wa' || value[i] === 'at')) {\n // Start and end X\n if (path[i + 5] === path[i + 7]) {\n path[i + 7] += value[i + 7] > value[i + 5] ? 1 : -1;\n }\n // Start and end Y\n if (path[i + 6] === path[i + 8]) {\n path[i + 8] += value[i + 8] > value[i + 6] ? 1 : -1;\n }\n }\n }\n }\n\n\n // Loop up again to handle path shortcuts (#2132)\n /*while (i++ < path.length) {\n if (path[i] === 'H') { // horizontal line to\n path[i] = 'L';\n path.splice(i + 2, 0, path[i - 1]);\n } else if (path[i] === 'V') { // vertical line to\n path[i] = 'L';\n path.splice(i + 1, 0, path[i - 2]);\n }\n }*/\n return path.join(' ') || 'x';\n },\n\n /**\n * Set the element's clipping to a predefined rectangle\n *\n * @param {String} id The id of the clip rectangle\n */\n clip: function(clipRect) {\n var wrapper = this,\n clipMembers,\n cssRet;\n\n if (clipRect) {\n clipMembers = clipRect.members;\n erase(clipMembers, wrapper); // Ensure unique list of elements (#1258)\n clipMembers.push(wrapper);\n wrapper.destroyClip = function() {\n erase(clipMembers, wrapper);\n };\n cssRet = clipRect.getCSS(wrapper);\n\n } else {\n if (wrapper.destroyClip) {\n wrapper.destroyClip();\n }\n cssRet = {\n clip: wrapper.docMode8 ? 'inherit' : 'rect(auto)'\n }; // #1214\n }\n\n return wrapper.css(cssRet);\n\n },\n\n /**\n * Set styles for the element\n * @param {Object} styles\n */\n css: SVGElement.prototype.htmlCss,\n\n /**\n * Removes a child either by removeChild or move to garbageBin.\n * Issue 490; in VML removeChild results in Orphaned nodes according to sIEve, discardElement does not.\n */\n safeRemoveChild: function(element) {\n // discardElement will detach the node from its parent before attaching it\n // to the garbage bin. Therefore it is important that the node is attached and have parent.\n if (element.parentNode) {\n discardElement(element);\n }\n },\n\n /**\n * Extend element.destroy by removing it from the clip members array\n */\n destroy: function() {\n if (this.destroyClip) {\n this.destroyClip();\n }\n\n return SVGElement.prototype.destroy.apply(this);\n },\n\n /**\n * Add an event listener. VML override for normalizing event parameters.\n * @param {String} eventType\n * @param {Function} handler\n */\n on: function(eventType, handler) {\n // simplest possible event model for internal use\n this.element['on' + eventType] = function() {\n var evt = win.event;\n evt.target = evt.srcElement;\n handler(evt);\n };\n return this;\n },\n\n /**\n * In stacked columns, cut off the shadows so that they don't overlap\n */\n cutOffPath: function(path, length) {\n\n var len;\n\n path = path.split(/[ ,]/); // The extra comma tricks the trailing comma remover in \"gulp scripts\" task\n len = path.length;\n\n if (len === 9 || len === 11) {\n path[len - 4] = path[len - 2] = pInt(path[len - 2]) - 10 * length;\n }\n return path.join(' ');\n },\n\n /**\n * Apply a drop shadow by copying elements and giving them different strokes\n * @param {Boolean|Object} shadowOptions\n */\n shadow: function(shadowOptions, group, cutOff) {\n var shadows = [],\n i,\n element = this.element,\n renderer = this.renderer,\n shadow,\n elemStyle = element.style,\n markup,\n path = element.path,\n strokeWidth,\n modifiedPath,\n shadowWidth,\n shadowElementOpacity;\n\n // some times empty paths are not strings\n if (path && typeof path.value !== 'string') {\n path = 'x';\n }\n modifiedPath = path;\n\n if (shadowOptions) {\n shadowWidth = pick(shadowOptions.width, 3);\n shadowElementOpacity = (shadowOptions.opacity || 0.15) / shadowWidth;\n for (i = 1; i <= 3; i++) {\n\n strokeWidth = (shadowWidth * 2) + 1 - (2 * i);\n\n // Cut off shadows for stacked column items\n if (cutOff) {\n modifiedPath = this.cutOffPath(path.value, strokeWidth + 0.5);\n }\n\n markup = [''\n ];\n\n shadow = createElement(renderer.prepVML(markup),\n null, {\n left: pInt(elemStyle.left) + pick(shadowOptions.offsetX, 1),\n top: pInt(elemStyle.top) + pick(shadowOptions.offsetY, 1)\n }\n );\n if (cutOff) {\n shadow.cutOff = strokeWidth + 1;\n }\n\n // apply the opacity\n markup = [\n ''\n ];\n createElement(renderer.prepVML(markup), null, null, shadow);\n\n\n // insert it\n if (group) {\n group.element.appendChild(shadow);\n } else {\n element.parentNode.insertBefore(shadow, element);\n }\n\n // record it\n shadows.push(shadow);\n\n }\n\n this.shadows = shadows;\n }\n return this;\n },\n updateShadows: noop, // Used in SVG only\n\n setAttr: function(key, value) {\n if (this.docMode8) { // IE8 setAttribute bug\n this.element[key] = value;\n } else {\n this.element.setAttribute(key, value);\n }\n },\n classSetter: function(value) {\n // IE8 Standards mode has problems retrieving the className unless set like this.\n // IE8 Standards can't set the class name before the element is appended.\n (this.added ? this.element : this).className = value;\n },\n dashstyleSetter: function(value, key, element) {\n var strokeElem = element.getElementsByTagName('stroke')[0] ||\n createElement(this.renderer.prepVML(['']), null, null, element);\n strokeElem[key] = value || 'solid';\n this[key] = value;\n /* because changing stroke-width will change the dash length\n and cause an epileptic effect */\n },\n dSetter: function(value, key, element) {\n var i,\n shadows = this.shadows;\n value = value || [];\n this.d = value.join && value.join(' '); // used in getter for animation\n\n element.path = value = this.pathToVML(value);\n\n // update shadows\n if (shadows) {\n i = shadows.length;\n while (i--) {\n shadows[i].path = shadows[i].cutOff ? this.cutOffPath(value, shadows[i].cutOff) : value;\n }\n }\n this.setAttr(key, value);\n },\n fillSetter: function(value, key, element) {\n var nodeName = element.nodeName;\n if (nodeName === 'SPAN') { // text color\n element.style.color = value;\n } else if (nodeName !== 'IMG') { // #1336\n element.filled = value !== 'none';\n this.setAttr('fillcolor', this.renderer.color(value, element, key, this));\n }\n },\n 'fill-opacitySetter': function(value, key, element) {\n createElement(\n this.renderer.prepVML(['<', key.split('-')[0], ' opacity=\"', value, '\"/>']),\n null,\n null,\n element\n );\n },\n opacitySetter: noop, // Don't bother - animation is too slow and filters introduce artifacts\n rotationSetter: function(value, key, element) {\n var style = element.style;\n this[key] = style[key] = value; // style is for #1873\n\n // Correction for the 1x1 size of the shape container. Used in gauge needles.\n style.left = -Math.round(Math.sin(value * deg2rad) + 1) + 'px';\n style.top = Math.round(Math.cos(value * deg2rad)) + 'px';\n },\n strokeSetter: function(value, key, element) {\n this.setAttr('strokecolor', this.renderer.color(value, element, key, this));\n },\n 'stroke-widthSetter': function(value, key, element) {\n element.stroked = !!value; // VML \"stroked\" attribute\n this[key] = value; // used in getter, issue #113\n if (isNumber(value)) {\n value += 'px';\n }\n this.setAttr('strokeweight', value);\n },\n titleSetter: function(value, key) {\n this.setAttr(key, value);\n },\n visibilitySetter: function(value, key, element) {\n\n // Handle inherited visibility\n if (value === 'inherit') {\n value = 'visible';\n }\n\n // Let the shadow follow the main element\n if (this.shadows) {\n each(this.shadows, function(shadow) {\n shadow.style[key] = value;\n });\n }\n\n // Instead of toggling the visibility CSS property, move the div out of the viewport.\n // This works around #61 and #586\n if (element.nodeName === 'DIV') {\n value = value === 'hidden' ? '-999em' : 0;\n\n // In order to redraw, IE7 needs the div to be visible when tucked away\n // outside the viewport. So the visibility is actually opposite of\n // the expected value. This applies to the tooltip only.\n if (!this.docMode8) {\n element.style[key] = value ? 'visible' : 'hidden';\n }\n key = 'top';\n }\n element.style[key] = value;\n },\n xSetter: function(value, key, element) {\n this[key] = value; // used in getter\n\n if (key === 'x') {\n key = 'left';\n } else if (key === 'y') {\n key = 'top';\n }\n /* else {\n value = Math.max(0, value); // don't set width or height below zero (#311)\n }*/\n\n // clipping rectangle special\n if (this.updateClipping) {\n this[key] = value; // the key is now 'left' or 'top' for 'x' and 'y'\n this.updateClipping();\n } else {\n // normal\n element.style[key] = value;\n }\n },\n zIndexSetter: function(value, key, element) {\n element.style[key] = value;\n }\n };\n VMLElement['stroke-opacitySetter'] = VMLElement['fill-opacitySetter'];\n H.VMLElement = VMLElement = extendClass(SVGElement, VMLElement);\n\n // Some shared setters\n VMLElement.prototype.ySetter =\n VMLElement.prototype.widthSetter =\n VMLElement.prototype.heightSetter =\n VMLElement.prototype.xSetter;\n\n\n /**\n * The VML renderer\n */\n VMLRendererExtension = { // inherit SVGRenderer\n\n Element: VMLElement,\n isIE8: win.navigator.userAgent.indexOf('MSIE 8.0') > -1,\n\n\n /**\n * Initialize the VMLRenderer\n * @param {Object} container\n * @param {Number} width\n * @param {Number} height\n */\n init: function(container, width, height) {\n var renderer = this,\n boxWrapper,\n box,\n css;\n\n renderer.alignedObjects = [];\n\n boxWrapper = renderer.createElement('div')\n .css({\n position: 'relative'\n });\n box = boxWrapper.element;\n container.appendChild(boxWrapper.element);\n\n\n // generate the containing box\n renderer.isVML = true;\n renderer.box = box;\n renderer.boxWrapper = boxWrapper;\n renderer.gradients = {};\n renderer.cache = {}; // Cache for numerical bounding boxes\n renderer.cacheKeys = [];\n renderer.imgCount = 0;\n\n\n renderer.setSize(width, height, false);\n\n // The only way to make IE6 and IE7 print is to use a global namespace. However,\n // with IE8 the only way to make the dynamic shapes visible in screen and print mode\n // seems to be to add the xmlns attribute and the behaviour style inline.\n if (!doc.namespaces.hcv) {\n\n doc.namespaces.add('hcv', 'urn:schemas-microsoft-com:vml');\n\n // Setup default CSS (#2153, #2368, #2384)\n css = 'hcv\\\\:fill, hcv\\\\:path, hcv\\\\:shape, hcv\\\\:stroke' +\n '{ behavior:url(#default#VML); display: inline-block; } ';\n try {\n doc.createStyleSheet().cssText = css;\n } catch (e) {\n doc.styleSheets[0].cssText += css;\n }\n\n }\n },\n\n\n /**\n * Detect whether the renderer is hidden. This happens when one of the parent elements\n * has display: none\n */\n isHidden: function() {\n return !this.box.offsetWidth;\n },\n\n /**\n * Define a clipping rectangle. In VML it is accomplished by storing the values\n * for setting the CSS style to all associated members.\n *\n * @param {Number} x\n * @param {Number} y\n * @param {Number} width\n * @param {Number} height\n */\n clipRect: function(x, y, width, height) {\n\n // create a dummy element\n var clipRect = this.createElement(),\n isObj = isObject(x);\n\n // mimic a rectangle with its style object for automatic updating in attr\n return extend(clipRect, {\n members: [],\n count: 0,\n left: (isObj ? x.x : x) + 1,\n top: (isObj ? x.y : y) + 1,\n width: (isObj ? x.width : width) - 1,\n height: (isObj ? x.height : height) - 1,\n getCSS: function(wrapper) {\n var element = wrapper.element,\n nodeName = element.nodeName,\n isShape = nodeName === 'shape',\n inverted = wrapper.inverted,\n rect = this,\n top = rect.top - (isShape ? element.offsetTop : 0),\n left = rect.left,\n right = left + rect.width,\n bottom = top + rect.height,\n ret = {\n clip: 'rect(' +\n Math.round(inverted ? left : top) + 'px,' +\n Math.round(inverted ? bottom : right) + 'px,' +\n Math.round(inverted ? right : bottom) + 'px,' +\n Math.round(inverted ? top : left) + 'px)'\n };\n\n // issue 74 workaround\n if (!inverted && wrapper.docMode8 && nodeName === 'DIV') {\n extend(ret, {\n width: right + 'px',\n height: bottom + 'px'\n });\n }\n return ret;\n },\n\n // used in attr and animation to update the clipping of all members\n updateClipping: function() {\n each(clipRect.members, function(member) {\n // Member.element is falsy on deleted series, like in\n // stock/members/series-remove demo. Should be removed\n // from members, but this will do.\n if (member.element) {\n member.css(clipRect.getCSS(member));\n }\n });\n }\n });\n\n },\n\n\n /**\n * Take a color and return it if it's a string, make it a gradient if it's a\n * gradient configuration object, and apply opacity.\n *\n * @param {Object} color The color or config object\n */\n color: function(color, elem, prop, wrapper) {\n var renderer = this,\n colorObject,\n regexRgba = /^rgba/,\n markup,\n fillType,\n ret = 'none';\n\n // Check for linear or radial gradient\n if (color && color.linearGradient) {\n fillType = 'gradient';\n } else if (color && color.radialGradient) {\n fillType = 'pattern';\n }\n\n\n if (fillType) {\n\n var stopColor,\n stopOpacity,\n gradient = color.linearGradient || color.radialGradient,\n x1,\n y1,\n x2,\n y2,\n opacity1,\n opacity2,\n color1,\n color2,\n fillAttr = '',\n stops = color.stops,\n firstStop,\n lastStop,\n colors = [],\n addFillNode = function() {\n // Add the fill subnode. When colors attribute is used, the meanings of opacity and o:opacity2\n // are reversed.\n markup = [''\n ];\n createElement(renderer.prepVML(markup), null, null, elem);\n };\n\n // Extend from 0 to 1\n firstStop = stops[0];\n lastStop = stops[stops.length - 1];\n if (firstStop[0] > 0) {\n stops.unshift([\n 0,\n firstStop[1]\n ]);\n }\n if (lastStop[0] < 1) {\n stops.push([\n 1,\n lastStop[1]\n ]);\n }\n\n // Compute the stops\n each(stops, function(stop, i) {\n if (regexRgba.test(stop[1])) {\n colorObject = H.color(stop[1]);\n stopColor = colorObject.get('rgb');\n stopOpacity = colorObject.get('a');\n } else {\n stopColor = stop[1];\n stopOpacity = 1;\n }\n\n // Build the color attribute\n colors.push((stop[0] * 100) + '% ' + stopColor);\n\n // Only start and end opacities are allowed, so we use the first and the last\n if (!i) {\n opacity1 = stopOpacity;\n color2 = stopColor;\n } else {\n opacity2 = stopOpacity;\n color1 = stopColor;\n }\n });\n\n // Apply the gradient to fills only.\n if (prop === 'fill') {\n\n // Handle linear gradient angle\n if (fillType === 'gradient') {\n x1 = gradient.x1 || gradient[0] || 0;\n y1 = gradient.y1 || gradient[1] || 0;\n x2 = gradient.x2 || gradient[2] || 0;\n y2 = gradient.y2 || gradient[3] || 0;\n fillAttr = 'angle=\"' + (90 - Math.atan(\n (y2 - y1) / // y vector\n (x2 - x1) // x vector\n ) * 180 / Math.PI) + '\"';\n\n addFillNode();\n\n // Radial (circular) gradient\n } else {\n\n var r = gradient.r,\n sizex = r * 2,\n sizey = r * 2,\n cx = gradient.cx,\n cy = gradient.cy,\n radialReference = elem.radialReference,\n bBox,\n applyRadialGradient = function() {\n if (radialReference) {\n bBox = wrapper.getBBox();\n cx += (radialReference[0] - bBox.x) / bBox.width - 0.5;\n cy += (radialReference[1] - bBox.y) / bBox.height - 0.5;\n sizex *= radialReference[2] / bBox.width;\n sizey *= radialReference[2] / bBox.height;\n }\n fillAttr = 'src=\"' + H.getOptions().global.VMLRadialGradientURL + '\" ' +\n 'size=\"' + sizex + ',' + sizey + '\" ' +\n 'origin=\"0.5,0.5\" ' +\n 'position=\"' + cx + ',' + cy + '\" ' +\n 'color2=\"' + color2 + '\" ';\n\n addFillNode();\n };\n\n // Apply radial gradient\n if (wrapper.added) {\n applyRadialGradient();\n } else {\n // We need to know the bounding box to get the size and position right\n wrapper.onAdd = applyRadialGradient;\n }\n\n // The fill element's color attribute is broken in IE8 standards mode, so we\n // need to set the parent shape's fillcolor attribute instead.\n ret = color1;\n }\n\n // Gradients are not supported for VML stroke, return the first color. #722.\n } else {\n ret = stopColor;\n }\n\n // If the color is an rgba color, split it and add a fill node\n // to hold the opacity component\n } else if (regexRgba.test(color) && elem.tagName !== 'IMG') {\n\n colorObject = H.color(color);\n\n wrapper[prop + '-opacitySetter'](colorObject.get('a'), prop, elem);\n\n ret = colorObject.get('rgb');\n\n\n } else {\n var propNodes = elem.getElementsByTagName(prop); // 'stroke' or 'fill' node\n if (propNodes.length) {\n propNodes[0].opacity = 1;\n propNodes[0].type = 'solid';\n }\n ret = color;\n }\n\n return ret;\n },\n\n /**\n * Take a VML string and prepare it for either IE8 or IE6/IE7.\n * @param {Array} markup A string array of the VML markup to prepare\n */\n prepVML: function(markup) {\n var vmlStyle = 'display:inline-block;behavior:url(#default#VML);',\n isIE8 = this.isIE8;\n\n markup = markup.join('');\n\n if (isIE8) { // add xmlns and style inline\n markup = markup.replace('/>', ' xmlns=\"urn:schemas-microsoft-com:vml\" />');\n if (markup.indexOf('style=\"') === -1) {\n markup = markup.replace('/>', ' style=\"' + vmlStyle + '\" />');\n } else {\n markup = markup.replace('style=\"', 'style=\"' + vmlStyle);\n }\n\n } else { // add namespace\n markup = markup.replace('<', ' 1) {\n obj.attr({\n x: x,\n y: y,\n width: width,\n height: height\n });\n }\n return obj;\n },\n\n /**\n * For rectangles, VML uses a shape for rect to overcome bugs and rotation problems\n */\n createElement: function(nodeName) {\n return nodeName === 'rect' ?\n this.symbol(nodeName) :\n SVGRenderer.prototype.createElement.call(this, nodeName);\n },\n\n /**\n * In the VML renderer, each child of an inverted div (group) is inverted\n * @param {Object} element\n * @param {Object} parentNode\n */\n invertChild: function(element, parentNode) {\n var ren = this,\n parentStyle = parentNode.style,\n imgStyle = element.tagName === 'IMG' && element.style; // #1111\n\n css(element, {\n flip: 'x',\n left: pInt(parentStyle.width) - (imgStyle ? pInt(imgStyle.top) : 1),\n top: pInt(parentStyle.height) - (imgStyle ? pInt(imgStyle.left) : 1),\n rotation: -90\n });\n\n // Recursively invert child elements, needed for nested composite\n // shapes like box plots and error bars. #1680, #1806.\n each(element.childNodes, function(child) {\n ren.invertChild(child, element);\n });\n },\n\n /**\n * Symbol definitions that override the parent SVG renderer's symbols\n *\n */\n symbols: {\n // VML specific arc function\n arc: function(x, y, w, h, options) {\n var start = options.start,\n end = options.end,\n radius = options.r || w || h,\n innerRadius = options.innerR,\n cosStart = Math.cos(start),\n sinStart = Math.sin(start),\n cosEnd = Math.cos(end),\n sinEnd = Math.sin(end),\n ret;\n\n if (end - start === 0) { // no angle, don't show it.\n return ['x'];\n }\n\n ret = [\n 'wa', // clockwise arc to\n x - radius, // left\n y - radius, // top\n x + radius, // right\n y + radius, // bottom\n x + radius * cosStart, // start x\n y + radius * sinStart, // start y\n x + radius * cosEnd, // end x\n y + radius * sinEnd // end y\n ];\n\n if (options.open && !innerRadius) {\n ret.push(\n 'e',\n 'M',\n x, // - innerRadius,\n y // - innerRadius\n );\n }\n\n ret.push(\n 'at', // anti clockwise arc to\n x - innerRadius, // left\n y - innerRadius, // top\n x + innerRadius, // right\n y + innerRadius, // bottom\n x + innerRadius * cosEnd, // start x\n y + innerRadius * sinEnd, // start y\n x + innerRadius * cosStart, // end x\n y + innerRadius * sinStart, // end y\n 'x', // finish path\n 'e' // close\n );\n\n ret.isArc = true;\n return ret;\n\n },\n // Add circle symbol path. This performs significantly faster than v:oval.\n circle: function(x, y, w, h, wrapper) {\n\n if (wrapper && defined(wrapper.r)) {\n w = h = 2 * wrapper.r;\n }\n\n // Center correction, #1682\n if (wrapper && wrapper.isCircle) {\n x -= w / 2;\n y -= h / 2;\n }\n\n // Return the path\n return [\n 'wa', // clockwisearcto\n x, // left\n y, // top\n x + w, // right\n y + h, // bottom\n x + w, // start x\n y + h / 2, // start y\n x + w, // end x\n y + h / 2, // end y\n //'x', // finish path\n 'e' // close\n ];\n },\n /**\n * Add rectangle symbol path which eases rotation and omits arcsize problems\n * compared to the built-in VML roundrect shape. When borders are not rounded,\n * use the simpler square path, else use the callout path without the arrow.\n */\n rect: function(x, y, w, h, options) {\n return SVGRenderer.prototype.symbols[!defined(options) || !options.r ? 'square' : 'callout'].call(0, x, y, w, h, options);\n }\n }\n };\n H.VMLRenderer = VMLRenderer = function() {\n this.init.apply(this, arguments);\n };\n VMLRenderer.prototype = merge(SVGRenderer.prototype, VMLRendererExtension);\n\n // general renderer\n H.Renderer = VMLRenderer;\n }\n\n // This method is used with exporting in old IE, when emulating SVG (see #2314)\n SVGRenderer.prototype.measureSpanWidth = function(text, styles) {\n var measuringSpan = doc.createElement('span'),\n offsetWidth,\n textNode = doc.createTextNode(text);\n\n measuringSpan.appendChild(textNode);\n css(measuringSpan, styles);\n this.box.appendChild(measuringSpan);\n offsetWidth = measuringSpan.offsetWidth;\n discardElement(measuringSpan); // #2463\n return offsetWidth;\n };\n\n\n /* ****************************************************************************\n * *\n * END OF INTERNET EXPLORER <= 8 SPECIFIC CODE *\n * *\n *****************************************************************************/\n\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var color = H.color,\n each = H.each,\n getTZOffset = H.getTZOffset,\n isTouchDevice = H.isTouchDevice,\n merge = H.merge,\n pick = H.pick,\n svg = H.svg,\n win = H.win;\n\n /* ****************************************************************************\n * Handle the options *\n *****************************************************************************/\n H.defaultOptions = {\n\n colors: '#7cb5ec #434348 #90ed7d #f7a35c #8085e9 #f15c80 #e4d354 #2b908f #f45b5b #91e8e1'.split(' '),\n\n symbols: ['circle', 'diamond', 'square', 'triangle', 'triangle-down'],\n lang: {\n loading: 'Loading...',\n months: [\n 'January', 'February', 'March', 'April', 'May', 'June', 'July',\n 'August', 'September', 'October', 'November', 'December'\n ],\n shortMonths: [\n 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',\n 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'\n ],\n weekdays: [\n 'Sunday', 'Monday', 'Tuesday', 'Wednesday',\n 'Thursday', 'Friday', 'Saturday'\n ],\n // invalidDate: '',\n decimalPoint: '.',\n numericSymbols: ['k', 'M', 'G', 'T', 'P', 'E'], // SI prefixes used in axis labels\n resetZoom: 'Reset zoom',\n resetZoomTitle: 'Reset zoom level 1:1',\n thousandsSep: ' '\n },\n global: {\n useUTC: true,\n //timezoneOffset: 0,\n\n VMLRadialGradientURL: 'http://code.highcharts.com/5.0.12/gfx/vml-radial-gradient.png'\n\n },\n chart: {\n //animation: true,\n //alignTicks: false,\n //reflow: true,\n //className: null,\n //events: { load, selection },\n //margin: [null],\n //marginTop: null,\n //marginRight: null,\n //marginBottom: null,\n //marginLeft: null,\n borderRadius: 0,\n\n defaultSeriesType: 'line',\n ignoreHiddenSeries: true,\n //inverted: false,\n spacing: [10, 10, 15, 10],\n //spacingTop: 10,\n //spacingRight: 10,\n //spacingBottom: 15,\n //spacingLeft: 10,\n //zoomType: ''\n resetZoomButton: {\n theme: {\n zIndex: 20\n },\n position: {\n align: 'right',\n x: -10,\n //verticalAlign: 'top',\n y: 10\n }\n // relativeTo: 'plot'\n },\n width: null,\n height: null,\n\n\n borderColor: '#335cad',\n //borderWidth: 0,\n //style: {\n // fontFamily: '\"Lucida Grande\", \"Lucida Sans Unicode\", Verdana, Arial, Helvetica, sans-serif', // default font\n // fontSize: '12px'\n //},\n backgroundColor: '#ffffff',\n //plotBackgroundColor: null,\n plotBorderColor: '#cccccc'\n //plotBorderWidth: 0,\n //plotShadow: false\n\n },\n title: {\n text: 'Chart title',\n align: 'center',\n // floating: false,\n margin: 15,\n // x: 0,\n // verticalAlign: 'top',\n // y: null,\n // style: {}, // defined inline\n widthAdjust: -44\n\n },\n subtitle: {\n text: '',\n align: 'center',\n // floating: false\n // x: 0,\n // verticalAlign: 'top',\n // y: null,\n // style: {}, // defined inline\n widthAdjust: -44\n },\n\n plotOptions: {},\n labels: {\n //items: [],\n style: {\n //font: defaultFont,\n position: 'absolute',\n color: '#333333'\n }\n },\n legend: {\n enabled: true,\n align: 'center',\n //floating: false,\n layout: 'horizontal',\n labelFormatter: function() {\n return this.name;\n },\n //borderWidth: 0,\n borderColor: '#999999',\n borderRadius: 0,\n navigation: {\n\n activeColor: '#003399',\n inactiveColor: '#cccccc'\n\n // animation: true,\n // arrowSize: 12\n // style: {} // text styles\n },\n // margin: 20,\n // reversed: false,\n // backgroundColor: null,\n /*style: {\n padding: '5px'\n },*/\n\n itemStyle: {\n color: '#333333',\n fontSize: '12px',\n fontWeight: 'bold',\n textOverflow: 'ellipsis'\n },\n itemHoverStyle: {\n //cursor: 'pointer', removed as of #601\n color: '#000000'\n },\n itemHiddenStyle: {\n color: '#cccccc'\n },\n shadow: false,\n\n itemCheckboxStyle: {\n position: 'absolute',\n width: '13px', // for IE precision\n height: '13px'\n },\n // itemWidth: undefined,\n squareSymbol: true,\n // symbolRadius: 0,\n // symbolWidth: 16,\n symbolPadding: 5,\n verticalAlign: 'bottom',\n // width: undefined,\n x: 0,\n y: 0,\n title: {\n //text: null,\n\n style: {\n fontWeight: 'bold'\n }\n\n }\n },\n\n loading: {\n // hideDuration: 100,\n // showDuration: 0,\n\n labelStyle: {\n fontWeight: 'bold',\n position: 'relative',\n top: '45%'\n },\n style: {\n position: 'absolute',\n backgroundColor: '#ffffff',\n opacity: 0.5,\n textAlign: 'center'\n }\n\n },\n\n tooltip: {\n enabled: true,\n animation: svg,\n //crosshairs: null,\n borderRadius: 3,\n dateTimeLabelFormats: {\n millisecond: '%A, %b %e, %H:%M:%S.%L',\n second: '%A, %b %e, %H:%M:%S',\n minute: '%A, %b %e, %H:%M',\n hour: '%A, %b %e, %H:%M',\n day: '%A, %b %e, %Y',\n week: 'Week from %A, %b %e, %Y',\n month: '%B %Y',\n year: '%Y'\n },\n footerFormat: '',\n //formatter: defaultFormatter,\n /* todo: em font-size when finished comparing against HC4\n headerFormat: '{point.key}
',\n */\n padding: 8,\n\n //shape: 'callout',\n //shared: false,\n snap: isTouchDevice ? 25 : 10,\n\n backgroundColor: color('#f7f7f7').setOpacity(0.85).get(),\n borderWidth: 1,\n headerFormat: '{point.key}
',\n pointFormat: '\\u25CF {series.name}: {point.y}
',\n shadow: true,\n style: {\n color: '#333333',\n cursor: 'default',\n fontSize: '12px',\n pointerEvents: 'none', // #1686 http://caniuse.com/#feat=pointer-events\n whiteSpace: 'nowrap'\n }\n\n //xDateFormat: '%A, %b %e, %Y',\n //valueDecimals: null,\n //valuePrefix: '',\n //valueSuffix: ''\n },\n\n credits: {\n enabled: true,\n href: 'http://www.highcharts.com',\n position: {\n align: 'right',\n x: -10,\n verticalAlign: 'bottom',\n y: -5\n },\n\n style: {\n cursor: 'pointer',\n color: '#999999',\n fontSize: '9px'\n },\n\n text: 'Highcharts.com'\n }\n };\n\n\n\n /**\n * Sets the getTimezoneOffset function. If the timezone option is set, a default\n * getTimezoneOffset function with that timezone is returned. If not, the\n * specified getTimezoneOffset function is returned. If neither are specified,\n * undefined is returned.\n * @return {function} a getTimezoneOffset function or undefined\n */\n function getTimezoneOffsetOption() {\n var globalOptions = H.defaultOptions.global,\n moment = win.moment;\n\n if (globalOptions.timezone) {\n if (!moment) {\n // getTimezoneOffset-function stays undefined because it depends on\n // Moment.js\n H.error(25);\n\n } else {\n return function(timestamp) {\n return -moment.tz(\n timestamp,\n globalOptions.timezone\n ).utcOffset();\n };\n }\n }\n\n // If not timezone is set, look for the getTimezoneOffset callback\n return globalOptions.useUTC && globalOptions.getTimezoneOffset;\n }\n\n /**\n * Set the time methods globally based on the useUTC option. Time method can be\n * either local time or UTC (default). It is called internally on initiating\n * Highcharts and after running `Highcharts.setOptions`.\n *\n * @private\n */\n function setTimeMethods() {\n var globalOptions = H.defaultOptions.global,\n Date,\n useUTC = globalOptions.useUTC,\n GET = useUTC ? 'getUTC' : 'get',\n SET = useUTC ? 'setUTC' : 'set';\n\n H.Date = Date = globalOptions.Date || win.Date; // Allow using a different Date class\n Date.hcTimezoneOffset = useUTC && globalOptions.timezoneOffset;\n Date.hcGetTimezoneOffset = getTimezoneOffsetOption();\n Date.hcMakeTime = function(year, month, date, hours, minutes, seconds) {\n var d;\n if (useUTC) {\n d = Date.UTC.apply(0, arguments);\n d += getTZOffset(d);\n } else {\n d = new Date(\n year,\n month,\n pick(date, 1),\n pick(hours, 0),\n pick(minutes, 0),\n pick(seconds, 0)\n ).getTime();\n }\n return d;\n };\n each(['Minutes', 'Hours', 'Day', 'Date', 'Month', 'FullYear'], function(s) {\n Date['hcGet' + s] = GET + s;\n });\n each(['Milliseconds', 'Seconds', 'Minutes', 'Hours', 'Date', 'Month', 'FullYear'], function(s) {\n Date['hcSet' + s] = SET + s;\n });\n }\n\n /**\n * Merge the default options with custom options and return the new options\n * structure. Commonly used for defining reusable templates.\n *\n * @function #setOptions\n * @memberOf Highcharts\n * @sample highcharts/global/useutc-false Setting a global option\n * @sample highcharts/members/setoptions Applying a global theme\n * @param {Object} options The new custom chart options.\n * @returns {Object} Updated options.\n */\n H.setOptions = function(options) {\n\n // Copy in the default options\n H.defaultOptions = merge(true, H.defaultOptions, options);\n\n // Apply UTC\n setTimeMethods();\n\n return H.defaultOptions;\n };\n\n /**\n * Get the updated default options. Until 3.0.7, merely exposing defaultOptions for outside modules\n * wasn't enough because the setOptions method created a new object.\n */\n H.getOptions = function() {\n return H.defaultOptions;\n };\n\n\n // Series defaults\n H.defaultPlotOptions = H.defaultOptions.plotOptions;\n\n // set the default time methods\n setTimeMethods();\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var correctFloat = H.correctFloat,\n defined = H.defined,\n destroyObjectProperties = H.destroyObjectProperties,\n isNumber = H.isNumber,\n merge = H.merge,\n pick = H.pick,\n deg2rad = H.deg2rad;\n\n /**\n * The Tick class\n */\n H.Tick = function(axis, pos, type, noLabel) {\n this.axis = axis;\n this.pos = pos;\n this.type = type || '';\n this.isNew = true;\n this.isNewLabel = true;\n\n if (!type && !noLabel) {\n this.addLabel();\n }\n };\n\n H.Tick.prototype = {\n /**\n * Write the tick label\n */\n addLabel: function() {\n var tick = this,\n axis = tick.axis,\n options = axis.options,\n chart = axis.chart,\n categories = axis.categories,\n names = axis.names,\n pos = tick.pos,\n labelOptions = options.labels,\n str,\n tickPositions = axis.tickPositions,\n isFirst = pos === tickPositions[0],\n isLast = pos === tickPositions[tickPositions.length - 1],\n value = categories ?\n pick(categories[pos], names[pos], pos) :\n pos,\n label = tick.label,\n tickPositionInfo = tickPositions.info,\n dateTimeLabelFormat;\n\n // Set the datetime label format. If a higher rank is set for this position, use that. If not,\n // use the general format.\n if (axis.isDatetimeAxis && tickPositionInfo) {\n dateTimeLabelFormat =\n options.dateTimeLabelFormats[\n tickPositionInfo.higherRanks[pos] || tickPositionInfo.unitName\n ];\n }\n // set properties for access in render method\n tick.isFirst = isFirst;\n tick.isLast = isLast;\n\n // get the string\n str = axis.labelFormatter.call({\n axis: axis,\n chart: chart,\n isFirst: isFirst,\n isLast: isLast,\n dateTimeLabelFormat: dateTimeLabelFormat,\n value: axis.isLog ? correctFloat(axis.lin2log(value)) : value\n });\n\n // prepare CSS\n //css = width && { width: Math.max(1, Math.round(width - 2 * (labelOptions.padding || 10))) + 'px' };\n\n // first call\n if (!defined(label)) {\n\n tick.label = label =\n defined(str) && labelOptions.enabled ?\n chart.renderer.text(\n str,\n 0,\n 0,\n labelOptions.useHTML\n )\n\n // without position absolute, IE export sometimes is wrong\n .css(merge(labelOptions.style))\n\n .add(axis.labelGroup) :\n null;\n tick.labelLength = label && label.getBBox().width; // Un-rotated length\n tick.rotation = 0; // Base value to detect change for new calls to getBBox\n\n // update\n } else if (label) {\n label.attr({\n text: str\n });\n }\n },\n\n /**\n * Get the offset height or width of the label\n */\n getLabelSize: function() {\n return this.label ?\n this.label.getBBox()[this.axis.horiz ? 'height' : 'width'] :\n 0;\n },\n\n /**\n * Handle the label overflow by adjusting the labels to the left and right edge, or\n * hide them if they collide into the neighbour label.\n */\n handleOverflow: function(xy) {\n var axis = this.axis,\n pxPos = xy.x,\n chartWidth = axis.chart.chartWidth,\n spacing = axis.chart.spacing,\n leftBound = pick(axis.labelLeft, Math.min(axis.pos, spacing[3])),\n rightBound = pick(axis.labelRight, Math.max(axis.pos + axis.len, chartWidth - spacing[1])),\n label = this.label,\n rotation = this.rotation,\n factor = {\n left: 0,\n center: 0.5,\n right: 1\n }[axis.labelAlign],\n labelWidth = label.getBBox().width,\n slotWidth = axis.getSlotWidth(),\n modifiedSlotWidth = slotWidth,\n xCorrection = factor,\n goRight = 1,\n leftPos,\n rightPos,\n textWidth,\n css = {};\n\n // Check if the label overshoots the chart spacing box. If it does, move it.\n // If it now overshoots the slotWidth, add ellipsis.\n if (!rotation) {\n leftPos = pxPos - factor * labelWidth;\n rightPos = pxPos + (1 - factor) * labelWidth;\n\n if (leftPos < leftBound) {\n modifiedSlotWidth = xy.x + modifiedSlotWidth * (1 - factor) - leftBound;\n } else if (rightPos > rightBound) {\n modifiedSlotWidth = rightBound - xy.x + modifiedSlotWidth * factor;\n goRight = -1;\n }\n\n modifiedSlotWidth = Math.min(slotWidth, modifiedSlotWidth); // #4177\n if (modifiedSlotWidth < slotWidth && axis.labelAlign === 'center') {\n xy.x += goRight * (slotWidth - modifiedSlotWidth - xCorrection *\n (slotWidth - Math.min(labelWidth, modifiedSlotWidth)));\n }\n // If the label width exceeds the available space, set a text width to be\n // picked up below. Also, if a width has been set before, we need to set a new\n // one because the reported labelWidth will be limited by the box (#3938).\n if (labelWidth > modifiedSlotWidth || (axis.autoRotation && (label.styles || {}).width)) {\n textWidth = modifiedSlotWidth;\n }\n\n // Add ellipsis to prevent rotated labels to be clipped against the edge of the chart\n } else if (rotation < 0 && pxPos - factor * labelWidth < leftBound) {\n textWidth = Math.round(pxPos / Math.cos(rotation * deg2rad) - leftBound);\n } else if (rotation > 0 && pxPos + factor * labelWidth > rightBound) {\n textWidth = Math.round((chartWidth - pxPos) / Math.cos(rotation * deg2rad));\n }\n\n if (textWidth) {\n css.width = textWidth;\n if (!(axis.options.labels.style || {}).textOverflow) {\n css.textOverflow = 'ellipsis';\n }\n label.css(css);\n }\n },\n\n /**\n * Get the x and y position for ticks and labels\n */\n getPosition: function(horiz, pos, tickmarkOffset, old) {\n var axis = this.axis,\n chart = axis.chart,\n cHeight = (old && chart.oldChartHeight) || chart.chartHeight;\n\n return {\n x: horiz ?\n axis.translate(pos + tickmarkOffset, null, null, old) + axis.transB : axis.left + axis.offset +\n (axis.opposite ?\n ((old && chart.oldChartWidth) || chart.chartWidth) - axis.right - axis.left :\n 0\n ),\n\n y: horiz ?\n cHeight - axis.bottom + axis.offset - (axis.opposite ? axis.height : 0) : cHeight - axis.translate(pos + tickmarkOffset, null, null, old) - axis.transB\n };\n\n },\n\n /**\n * Get the x, y position of the tick label\n */\n getLabelPosition: function(x, y, label, horiz, labelOptions, tickmarkOffset, index, step) {\n var axis = this.axis,\n transA = axis.transA,\n reversed = axis.reversed,\n staggerLines = axis.staggerLines,\n rotCorr = axis.tickRotCorr || {\n x: 0,\n y: 0\n },\n yOffset = labelOptions.y,\n line;\n\n if (!defined(yOffset)) {\n if (axis.side === 0) {\n yOffset = label.rotation ? -8 : -label.getBBox().height;\n } else if (axis.side === 2) {\n yOffset = rotCorr.y + 8;\n } else {\n // #3140, #3140\n yOffset = Math.cos(label.rotation * deg2rad) * (rotCorr.y - label.getBBox(false, 0).height / 2);\n }\n }\n\n x = x + labelOptions.x + rotCorr.x - (tickmarkOffset && horiz ?\n tickmarkOffset * transA * (reversed ? -1 : 1) : 0);\n y = y + yOffset - (tickmarkOffset && !horiz ?\n tickmarkOffset * transA * (reversed ? 1 : -1) : 0);\n\n // Correct for staggered labels\n if (staggerLines) {\n line = (index / (step || 1) % staggerLines);\n if (axis.opposite) {\n line = staggerLines - line - 1;\n }\n y += line * (axis.labelOffset / staggerLines);\n }\n\n return {\n x: x,\n y: Math.round(y)\n };\n },\n\n /**\n * Extendible method to return the path of the marker\n */\n getMarkPath: function(x, y, tickLength, tickWidth, horiz, renderer) {\n return renderer.crispLine([\n 'M',\n x,\n y,\n 'L',\n x + (horiz ? 0 : -tickLength),\n y + (horiz ? tickLength : 0)\n ], tickWidth);\n },\n\n /**\n * Renders the gridLine.\n * @param {Boolean} old Whether or not the tick is old\n * @param {number} opacity The opacity of the grid line\n * @param {number} reverseCrisp Modifier for avoiding overlapping 1 or -1\n * @return {undefined}\n */\n renderGridLine: function(old, opacity, reverseCrisp) {\n var tick = this,\n axis = tick.axis,\n options = axis.options,\n gridLine = tick.gridLine,\n gridLinePath,\n attribs = {},\n pos = tick.pos,\n type = tick.type,\n tickmarkOffset = axis.tickmarkOffset,\n renderer = axis.chart.renderer;\n\n\n var gridPrefix = type ? type + 'Grid' : 'grid',\n gridLineWidth = options[gridPrefix + 'LineWidth'],\n gridLineColor = options[gridPrefix + 'LineColor'],\n dashStyle = options[gridPrefix + 'LineDashStyle'];\n\n\n if (!gridLine) {\n\n attribs.stroke = gridLineColor;\n attribs['stroke-width'] = gridLineWidth;\n if (dashStyle) {\n attribs.dashstyle = dashStyle;\n }\n\n if (!type) {\n attribs.zIndex = 1;\n }\n if (old) {\n attribs.opacity = 0;\n }\n tick.gridLine = gridLine = renderer.path()\n .attr(attribs)\n .addClass(\n 'highcharts-' + (type ? type + '-' : '') + 'grid-line'\n )\n .add(axis.gridGroup);\n }\n\n // If the parameter 'old' is set, the current call will be followed\n // by another call, therefore do not do any animations this time\n if (!old && gridLine) {\n gridLinePath = axis.getPlotLinePath(\n pos + tickmarkOffset,\n gridLine.strokeWidth() * reverseCrisp,\n old, true\n );\n if (gridLinePath) {\n gridLine[tick.isNew ? 'attr' : 'animate']({\n d: gridLinePath,\n opacity: opacity\n });\n }\n }\n },\n\n /**\n * Renders the tick mark.\n * @param {Object} xy The position vector of the mark\n * @param {number} xy.x The x position of the mark\n * @param {number} xy.y The y position of the mark\n * @param {number} opacity The opacity of the mark\n * @param {number} reverseCrisp Modifier for avoiding overlapping 1 or -1\n * @return {undefined}\n */\n renderMark: function(xy, opacity, reverseCrisp) {\n var tick = this,\n axis = tick.axis,\n options = axis.options,\n renderer = axis.chart.renderer,\n type = tick.type,\n tickPrefix = type ? type + 'Tick' : 'tick',\n tickSize = axis.tickSize(tickPrefix),\n mark = tick.mark,\n isNewMark = !mark,\n x = xy.x,\n y = xy.y;\n\n\n var tickWidth = pick(\n options[tickPrefix + 'Width'], !type && axis.isXAxis ? 1 : 0\n ), // X axis defaults to 1\n tickColor = options[tickPrefix + 'Color'];\n\n\n if (tickSize) {\n\n // negate the length\n if (axis.opposite) {\n tickSize[0] = -tickSize[0];\n }\n\n // First time, create it\n if (isNewMark) {\n tick.mark = mark = renderer.path()\n .addClass('highcharts-' + (type ? type + '-' : '') + 'tick')\n .add(axis.axisGroup);\n\n\n mark.attr({\n stroke: tickColor,\n 'stroke-width': tickWidth\n });\n\n }\n mark[isNewMark ? 'attr' : 'animate']({\n d: tick.getMarkPath(\n x,\n y,\n tickSize[0],\n mark.strokeWidth() * reverseCrisp,\n axis.horiz,\n renderer),\n opacity: opacity\n });\n\n }\n },\n\n /**\n * Renders the tick label.\n * Note: The label should already be created in init(), so it should only\n * have to be moved into place.\n * @param {Object} xy The position vector of the label\n * @param {number} xy.x The x position of the label\n * @param {number} xy.y The y position of the label\n * @param {Boolean} old Whether or not the tick is old\n * @param {number} opacity The opacity of the label\n * @param {number} index The index of the tick\n * @return {undefined}\n */\n renderLabel: function(xy, old, opacity, index) {\n var tick = this,\n axis = tick.axis,\n horiz = axis.horiz,\n options = axis.options,\n label = tick.label,\n labelOptions = options.labels,\n step = labelOptions.step,\n tickmarkOffset = axis.tickmarkOffset,\n show = true,\n x = xy.x,\n y = xy.y;\n if (label && isNumber(x)) {\n label.xy = xy = tick.getLabelPosition(\n x,\n y,\n label,\n horiz,\n labelOptions,\n tickmarkOffset,\n index,\n step\n );\n\n // Apply show first and show last. If the tick is both first and\n // last, it is a single centered tick, in which case we show the\n // label anyway (#2100).\n if (\n (\n tick.isFirst &&\n !tick.isLast &&\n !pick(options.showFirstLabel, 1)\n ) ||\n (\n tick.isLast &&\n !tick.isFirst &&\n !pick(options.showLastLabel, 1)\n )\n ) {\n show = false;\n\n // Handle label overflow and show or hide accordingly\n } else if (horiz && !axis.isRadial && !labelOptions.step &&\n !labelOptions.rotation && !old && opacity !== 0) {\n tick.handleOverflow(xy);\n }\n\n // apply step\n if (step && index % step) {\n // show those indices dividable by step\n show = false;\n }\n\n // Set the new position, and show or hide\n if (show && isNumber(xy.y)) {\n xy.opacity = opacity;\n label[tick.isNewLabel ? 'attr' : 'animate'](xy);\n tick.isNewLabel = false;\n } else {\n label.attr('y', -9999); // #1338\n tick.isNewLabel = true;\n }\n tick.isNew = false;\n }\n },\n\n /**\n * Put everything in place\n *\n * @param index {Number}\n * @param old {Boolean} Use old coordinates to prepare an animation into new\n * position\n */\n render: function(index, old, opacity) {\n var tick = this,\n axis = tick.axis,\n horiz = axis.horiz,\n pos = tick.pos,\n tickmarkOffset = axis.tickmarkOffset,\n xy = tick.getPosition(horiz, pos, tickmarkOffset, old),\n x = xy.x,\n y = xy.y,\n reverseCrisp = ((horiz && x === axis.pos + axis.len) ||\n (!horiz && y === axis.pos)) ? -1 : 1; // #1480, #1687\n\n opacity = pick(opacity, 1);\n this.isActive = true;\n\n // Create the grid line\n this.renderGridLine(old, opacity, reverseCrisp);\n\n // create the tick mark\n this.renderMark(xy, opacity, reverseCrisp);\n\n // the label is created on init - now move it into place\n this.renderLabel(xy, old, opacity, index);\n },\n\n /**\n * Destructor for the tick prototype\n */\n destroy: function() {\n destroyObjectProperties(this, this.axis);\n }\n };\n\n }(Highcharts));\n var Axis = (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n\n var addEvent = H.addEvent,\n animObject = H.animObject,\n arrayMax = H.arrayMax,\n arrayMin = H.arrayMin,\n color = H.color,\n correctFloat = H.correctFloat,\n defaultOptions = H.defaultOptions,\n defined = H.defined,\n deg2rad = H.deg2rad,\n destroyObjectProperties = H.destroyObjectProperties,\n each = H.each,\n extend = H.extend,\n fireEvent = H.fireEvent,\n format = H.format,\n getMagnitude = H.getMagnitude,\n grep = H.grep,\n inArray = H.inArray,\n isArray = H.isArray,\n isNumber = H.isNumber,\n isString = H.isString,\n merge = H.merge,\n normalizeTickInterval = H.normalizeTickInterval,\n objectEach = H.objectEach,\n pick = H.pick,\n removeEvent = H.removeEvent,\n splat = H.splat,\n syncTimeout = H.syncTimeout,\n Tick = H.Tick;\n\n /**\n * Create a new axis object. Called internally when instanciating a new chart or\n * adding axes by {@link Highcharts.Chart#addAxis}.\n *\n * A chart can have from 0 axes (pie chart) to multiples. In a normal, single\n * series cartesian chart, there is one X axis and one Y axis.\n * \n * The X axis or axes are referenced by {@link Highcharts.Chart.xAxis}, which is\n * an array of Axis objects. If there is only one axis, it can be referenced\n * through `chart.xAxis[0]`, and multiple axes have increasing indices. The same\n * pattern goes for Y axes.\n * \n * If you need to get the axes from a series object, use the `series.xAxis` and\n * `series.yAxis` properties. These are not arrays, as one series can only be\n * associated to one X and one Y axis.\n * \n * A third way to reference the axis programmatically is by `id`. Add an `id` in\n * the axis configuration options, and get the axis by\n * {@link Highcharts.Chart#get}.\n * \n * Configuration options for the axes are given in options.xAxis and\n * options.yAxis.\n * \n * @class Highcharts.Axis\n * @memberOf Highcharts\n * @param {Highcharts.Chart} chart - The Chart instance to apply the axis on.\n * @param {Object} options - Axis options\n */\n var Axis = function() {\n this.init.apply(this, arguments);\n };\n\n H.extend(Axis.prototype, /** @lends Highcharts.Axis.prototype */ {\n\n /**\n * Default options for the X axis - the Y axis has extended defaults.\n *\n * @private\n * @type {Object}\n */\n defaultOptions: {\n // allowDecimals: null,\n // alternateGridColor: null,\n // categories: [],\n dateTimeLabelFormats: {\n millisecond: '%H:%M:%S.%L',\n second: '%H:%M:%S',\n minute: '%H:%M',\n hour: '%H:%M',\n day: '%e. %b',\n week: '%e. %b',\n month: '%b \\'%y',\n year: '%Y'\n },\n endOnTick: false,\n // reversed: false,\n\n labels: {\n enabled: true,\n // rotation: 0,\n // align: 'center',\n // step: null,\n\n style: {\n color: '#666666',\n cursor: 'default',\n fontSize: '11px'\n },\n\n x: 0\n //y: undefined\n /*formatter: function () {\n return this.value;\n },*/\n },\n //linkedTo: null,\n //max: undefined,\n //min: undefined,\n minPadding: 0.01,\n maxPadding: 0.01,\n //minRange: null,\n //minorTickInterval: null,\n minorTickLength: 2,\n minorTickPosition: 'outside', // inside or outside\n //opposite: false,\n //offset: 0,\n //plotBands: [{\n // events: {},\n // zIndex: 1,\n // labels: { align, x, verticalAlign, y, style, rotation, textAlign }\n //}],\n //plotLines: [{\n // events: {}\n // dashStyle: {}\n // zIndex:\n // labels: { align, x, verticalAlign, y, style, rotation, textAlign }\n //}],\n //reversed: false,\n // showFirstLabel: true,\n // showLastLabel: true,\n startOfWeek: 1,\n startOnTick: false,\n //tickInterval: null,\n tickLength: 10,\n tickmarkPlacement: 'between', // on or between\n tickPixelInterval: 100,\n tickPosition: 'outside',\n title: {\n //text: null,\n align: 'middle', // low, middle or high\n //margin: 0 for horizontal, 10 for vertical axes,\n // reserveSpace: true,\n //rotation: 0,\n //side: 'outside',\n\n style: {\n color: '#666666'\n }\n\n //x: 0,\n //y: 0\n },\n type: 'linear', // linear, logarithmic or datetime\n //visible: true\n\n minorGridLineColor: '#f2f2f2',\n // minorGridLineDashStyle: null,\n minorGridLineWidth: 1,\n minorTickColor: '#999999',\n //minorTickWidth: 0,\n lineColor: '#ccd6eb',\n lineWidth: 1,\n gridLineColor: '#e6e6e6',\n // gridLineDashStyle: 'solid',\n // gridLineWidth: 0,\n tickColor: '#ccd6eb'\n // tickWidth: 1\n\n },\n\n /**\n * This options set extends the defaultOptions for Y axes.\n *\n * @private\n * @type {Object}\n */\n defaultYAxisOptions: {\n endOnTick: true,\n tickPixelInterval: 72,\n showLastLabel: true,\n labels: {\n x: -8\n },\n maxPadding: 0.05,\n minPadding: 0.05,\n startOnTick: true,\n title: {\n rotation: 270,\n text: 'Values'\n },\n stackLabels: {\n enabled: false,\n //align: dynamic,\n //y: dynamic,\n //x: dynamic,\n //verticalAlign: dynamic,\n //textAlign: dynamic,\n //rotation: 0,\n formatter: function() {\n return H.numberFormat(this.total, -1);\n },\n\n style: {\n fontSize: '11px',\n fontWeight: 'bold',\n color: '#000000',\n textOutline: '1px contrast'\n }\n\n },\n\n gridLineWidth: 1,\n lineWidth: 0\n // tickWidth: 0\n\n },\n\n /**\n * These options extend the defaultOptions for left axes.\n * \n * @private\n * @type {Object}\n */\n defaultLeftAxisOptions: {\n labels: {\n x: -15\n },\n title: {\n rotation: 270\n }\n },\n\n /**\n * These options extend the defaultOptions for right axes.\n *\n * @private\n * @type {Object}\n */\n defaultRightAxisOptions: {\n labels: {\n x: 15\n },\n title: {\n rotation: 90\n }\n },\n\n /**\n * These options extend the defaultOptions for bottom axes.\n *\n * @private\n * @type {Object}\n */\n defaultBottomAxisOptions: {\n labels: {\n autoRotation: [-45],\n x: 0\n // overflow: undefined,\n // staggerLines: null\n },\n title: {\n rotation: 0\n }\n },\n /**\n * These options extend the defaultOptions for top axes.\n *\n * @private\n * @type {Object}\n */\n defaultTopAxisOptions: {\n labels: {\n autoRotation: [-45],\n x: 0\n // overflow: undefined\n // staggerLines: null\n },\n title: {\n rotation: 0\n }\n },\n\n /**\n * Initialize the axis\n */\n init: function(chart, userOptions) {\n\n\n var isXAxis = userOptions.isX,\n axis = this;\n\n axis.chart = chart;\n\n // Flag, is the axis horizontal\n axis.horiz = chart.inverted && !axis.isZAxis ? !isXAxis : isXAxis;\n\n // Flag, isXAxis\n axis.isXAxis = isXAxis;\n axis.coll = axis.coll || (isXAxis ? 'xAxis' : 'yAxis');\n\n axis.opposite = userOptions.opposite; // needed in setOptions\n axis.side = userOptions.side || (axis.horiz ?\n (axis.opposite ? 0 : 2) : // top : bottom\n (axis.opposite ? 1 : 3)); // right : left\n\n axis.setOptions(userOptions);\n\n\n var options = this.options,\n type = options.type,\n isDatetimeAxis = type === 'datetime';\n\n axis.labelFormatter = options.labels.formatter ||\n axis.defaultLabelFormatter; // can be overwritten by dynamic format\n\n\n // Flag, stagger lines or not\n axis.userOptions = userOptions;\n\n //axis.axisTitleMargin = undefined,// = options.title.margin,\n axis.minPixelPadding = 0;\n\n axis.reversed = options.reversed;\n axis.visible = options.visible !== false;\n axis.zoomEnabled = options.zoomEnabled !== false;\n\n // Initial categories\n axis.hasNames = type === 'category' || options.categories === true;\n axis.categories = options.categories || axis.hasNames;\n axis.names = axis.names || []; // Preserve on update (#3830)\n\n // Elements\n //axis.axisGroup = undefined;\n //axis.gridGroup = undefined;\n //axis.axisTitle = undefined;\n //axis.axisLine = undefined;\n\n // Placeholder for plotlines and plotbands groups\n axis.plotLinesAndBandsGroups = {};\n\n // Shorthand types\n axis.isLog = type === 'logarithmic';\n axis.isDatetimeAxis = isDatetimeAxis;\n axis.positiveValuesOnly = axis.isLog && !axis.allowNegativeLog;\n\n // Flag, if axis is linked to another axis\n axis.isLinked = defined(options.linkedTo);\n // Linked axis.\n //axis.linkedParent = undefined;\n\n // Major ticks\n axis.ticks = {};\n axis.labelEdge = [];\n // Minor ticks\n axis.minorTicks = {};\n\n // List of plotLines/Bands\n axis.plotLinesAndBands = [];\n\n // Alternate bands\n axis.alternateBands = {};\n\n // Axis metrics\n //axis.left = undefined;\n //axis.top = undefined;\n //axis.width = undefined;\n //axis.height = undefined;\n //axis.bottom = undefined;\n //axis.right = undefined;\n //axis.transA = undefined;\n //axis.transB = undefined;\n //axis.oldTransA = undefined;\n axis.len = 0;\n //axis.oldMin = undefined;\n //axis.oldMax = undefined;\n //axis.oldUserMin = undefined;\n //axis.oldUserMax = undefined;\n //axis.oldAxisLength = undefined;\n axis.minRange = axis.userMinRange = options.minRange || options.maxZoom;\n axis.range = options.range;\n axis.offset = options.offset || 0;\n\n\n // Dictionary for stacks\n axis.stacks = {};\n axis.oldStacks = {};\n axis.stacksTouched = 0;\n\n // Min and max in the data\n //axis.dataMin = undefined,\n //axis.dataMax = undefined,\n\n // The axis range\n axis.max = null;\n axis.min = null;\n\n // User set min and max\n //axis.userMin = undefined,\n //axis.userMax = undefined,\n\n // Crosshair options\n axis.crosshair = pick(\n options.crosshair,\n splat(chart.options.tooltip.crosshairs)[isXAxis ? 0 : 1],\n false\n );\n\n var events = axis.options.events;\n\n // Register. Don't add it again on Axis.update().\n if (inArray(axis, chart.axes) === -1) { // \n if (isXAxis) { // #2713\n chart.axes.splice(chart.xAxis.length, 0, axis);\n } else {\n chart.axes.push(axis);\n }\n\n chart[axis.coll].push(axis);\n }\n\n axis.series = axis.series || []; // populated by Series\n\n // inverted charts have reversed xAxes as default\n if (chart.inverted && !axis.isZAxis && isXAxis && axis.reversed === undefined) {\n axis.reversed = true;\n }\n\n // register event listeners\n objectEach(events, function(event, eventType) {\n addEvent(axis, eventType, event);\n });\n\n // extend logarithmic axis\n axis.lin2log = options.linearToLogConverter || axis.lin2log;\n if (axis.isLog) {\n axis.val2lin = axis.log2lin;\n axis.lin2val = axis.lin2log;\n }\n },\n\n /**\n * Merge and set options\n */\n setOptions: function(userOptions) {\n this.options = merge(\n this.defaultOptions,\n this.coll === 'yAxis' && this.defaultYAxisOptions, [\n this.defaultTopAxisOptions,\n this.defaultRightAxisOptions,\n this.defaultBottomAxisOptions,\n this.defaultLeftAxisOptions\n ][this.side],\n merge(\n defaultOptions[this.coll], // if set in setOptions (#1053)\n userOptions\n )\n );\n },\n\n /**\n * The default label formatter. The context is a special config object for\n * the label. In apps, use the {@link\n * https://api.highcharts.com/highcharts/xAxis.labels.formatter|\n * labels.formatter} instead except when a modification is needed.\n *\n * @private\n */\n defaultLabelFormatter: function() {\n var axis = this.axis,\n value = this.value,\n categories = axis.categories,\n dateTimeLabelFormat = this.dateTimeLabelFormat,\n lang = defaultOptions.lang,\n numericSymbols = lang.numericSymbols,\n numSymMagnitude = lang.numericSymbolMagnitude || 1000,\n i = numericSymbols && numericSymbols.length,\n multi,\n ret,\n formatOption = axis.options.labels.format,\n\n // make sure the same symbol is added for all labels on a linear\n // axis\n numericSymbolDetector = axis.isLog ?\n Math.abs(value) :\n axis.tickInterval;\n\n if (formatOption) {\n ret = format(formatOption, this);\n\n } else if (categories) {\n ret = value;\n\n } else if (dateTimeLabelFormat) { // datetime axis\n ret = H.dateFormat(dateTimeLabelFormat, value);\n\n } else if (i && numericSymbolDetector >= 1000) {\n // Decide whether we should add a numeric symbol like k (thousands)\n // or M (millions). If we are to enable this in tooltip or other\n // places as well, we can move this logic to the numberFormatter and\n // enable it by a parameter.\n while (i-- && ret === undefined) {\n multi = Math.pow(numSymMagnitude, i + 1);\n if (\n numericSymbolDetector >= multi &&\n (value * 10) % multi === 0 &&\n numericSymbols[i] !== null &&\n value !== 0\n ) { // #5480\n ret = H.numberFormat(value / multi, -1) + numericSymbols[i];\n }\n }\n }\n\n if (ret === undefined) {\n if (Math.abs(value) >= 10000) { // add thousands separators\n ret = H.numberFormat(value, -1);\n } else { // small numbers\n ret = H.numberFormat(value, -1, undefined, ''); // #2466\n }\n }\n\n return ret;\n },\n\n /**\n * Get the minimum and maximum for the series of each axis\n */\n getSeriesExtremes: function() {\n var axis = this,\n chart = axis.chart;\n axis.hasVisibleSeries = false;\n\n // Reset properties in case we're redrawing (#3353)\n axis.dataMin = axis.dataMax = axis.threshold = null;\n axis.softThreshold = !axis.isXAxis;\n\n if (axis.buildStacks) {\n axis.buildStacks();\n }\n\n // loop through this axis' series\n each(axis.series, function(series) {\n\n if (series.visible || !chart.options.chart.ignoreHiddenSeries) {\n\n var seriesOptions = series.options,\n xData,\n threshold = seriesOptions.threshold,\n seriesDataMin,\n seriesDataMax;\n\n axis.hasVisibleSeries = true;\n\n // Validate threshold in logarithmic axes\n if (axis.positiveValuesOnly && threshold <= 0) {\n threshold = null;\n }\n\n // Get dataMin and dataMax for X axes\n if (axis.isXAxis) {\n xData = series.xData;\n if (xData.length) {\n // If xData contains values which is not numbers, then\n // filter them out. To prevent performance hit, we only\n // do this after we have already found seriesDataMin\n // because in most cases all data is valid. #5234.\n seriesDataMin = arrayMin(xData);\n if (!isNumber(seriesDataMin) &&\n !(seriesDataMin instanceof Date) // #5010\n ) {\n xData = grep(xData, function(x) {\n return isNumber(x);\n });\n seriesDataMin = arrayMin(xData); // Do it again with valid data\n }\n\n axis.dataMin = Math.min(\n pick(axis.dataMin, xData[0]),\n seriesDataMin\n );\n axis.dataMax = Math.max(\n pick(axis.dataMax, xData[0]),\n arrayMax(xData)\n );\n\n }\n\n // Get dataMin and dataMax for Y axes, as well as handle\n // stacking and processed data\n } else {\n\n // Get this particular series extremes\n series.getExtremes();\n seriesDataMax = series.dataMax;\n seriesDataMin = series.dataMin;\n\n // Get the dataMin and dataMax so far. If percentage is\n // used, the min and max are always 0 and 100. If\n // seriesDataMin and seriesDataMax is null, then series\n // doesn't have active y data, we continue with nulls\n if (defined(seriesDataMin) && defined(seriesDataMax)) {\n axis.dataMin = Math.min(\n pick(axis.dataMin, seriesDataMin),\n seriesDataMin\n );\n axis.dataMax = Math.max(\n pick(axis.dataMax, seriesDataMax),\n seriesDataMax\n );\n }\n\n // Adjust to threshold\n if (defined(threshold)) {\n axis.threshold = threshold;\n }\n // If any series has a hard threshold, it takes precedence\n if (!seriesOptions.softThreshold ||\n axis.positiveValuesOnly\n ) {\n axis.softThreshold = false;\n }\n }\n }\n });\n },\n\n /**\n * Translate from axis value to pixel position on the chart, or back\n *\n */\n translate: function(val, backwards, cvsCoord, old, handleLog, pointPlacement) {\n var axis = this.linkedParent || this, // #1417\n sign = 1,\n cvsOffset = 0,\n localA = old ? axis.oldTransA : axis.transA,\n localMin = old ? axis.oldMin : axis.min,\n returnValue,\n minPixelPadding = axis.minPixelPadding,\n doPostTranslate = (axis.isOrdinal || axis.isBroken || (axis.isLog && handleLog)) && axis.lin2val;\n\n if (!localA) {\n localA = axis.transA;\n }\n\n // In vertical axes, the canvas coordinates start from 0 at the top like in\n // SVG.\n if (cvsCoord) {\n sign *= -1; // canvas coordinates inverts the value\n cvsOffset = axis.len;\n }\n\n // Handle reversed axis\n if (axis.reversed) {\n sign *= -1;\n cvsOffset -= sign * (axis.sector || axis.len);\n }\n\n // From pixels to value\n if (backwards) { // reverse translation\n\n val = val * sign + cvsOffset;\n val -= minPixelPadding;\n returnValue = val / localA + localMin; // from chart pixel to value\n if (doPostTranslate) { // log and ordinal axes\n returnValue = axis.lin2val(returnValue);\n }\n\n // From value to pixels\n } else {\n if (doPostTranslate) { // log and ordinal axes\n val = axis.val2lin(val);\n }\n returnValue = sign * (val - localMin) * localA + cvsOffset +\n (sign * minPixelPadding) +\n (isNumber(pointPlacement) ? localA * pointPlacement : 0);\n }\n\n return returnValue;\n },\n\n /**\n * Translate a value in terms of axis units into pixels within the chart.\n * \n * @param {Number} value\n * A value in terms of axis units.\n * @param {Boolean} paneCoordinates\n * Whether to return the pixel coordinate relative to the chart or\n * just the axis/pane itself.\n * @return {Number} Pixel position of the value on the chart or axis.\n */\n toPixels: function(value, paneCoordinates) {\n return this.translate(value, false, !this.horiz, null, true) +\n (paneCoordinates ? 0 : this.pos);\n },\n\n /**\n * Translate a pixel position along the axis to a value in terms of axis\n * units.\n * @param {Number} pixel\n * The pixel value coordinate.\n * @param {Boolean} paneCoordiantes\n * Whether the input pixel is relative to the chart or just the\n * axis/pane itself.\n * @return {Number} The axis value.\n */\n toValue: function(pixel, paneCoordinates) {\n return this.translate(\n pixel - (paneCoordinates ? 0 : this.pos),\n true, !this.horiz,\n null,\n true\n );\n },\n\n /**\n * Create the path for a plot line that goes from the given value on\n * this axis, across the plot to the opposite side\n * @param {Number} value\n * @param {Number} lineWidth Used for calculation crisp line\n * @param {Number] old Use old coordinates (for resizing and rescaling)\n */\n getPlotLinePath: function(value, lineWidth, old, force, translatedValue) {\n var axis = this,\n chart = axis.chart,\n axisLeft = axis.left,\n axisTop = axis.top,\n x1,\n y1,\n x2,\n y2,\n cHeight = (old && chart.oldChartHeight) || chart.chartHeight,\n cWidth = (old && chart.oldChartWidth) || chart.chartWidth,\n skip,\n transB = axis.transB,\n /**\n * Check if x is between a and b. If not, either move to a/b or skip,\n * depending on the force parameter.\n */\n between = function(x, a, b) {\n if (x < a || x > b) {\n if (force) {\n x = Math.min(Math.max(a, x), b);\n } else {\n skip = true;\n }\n }\n return x;\n };\n\n translatedValue = pick(translatedValue, axis.translate(value, null, null, old));\n x1 = x2 = Math.round(translatedValue + transB);\n y1 = y2 = Math.round(cHeight - translatedValue - transB);\n if (!isNumber(translatedValue)) { // no min or max\n skip = true;\n\n } else if (axis.horiz) {\n y1 = axisTop;\n y2 = cHeight - axis.bottom;\n x1 = x2 = between(x1, axisLeft, axisLeft + axis.width);\n } else {\n x1 = axisLeft;\n x2 = cWidth - axis.right;\n y1 = y2 = between(y1, axisTop, axisTop + axis.height);\n }\n return skip && !force ?\n null :\n chart.renderer.crispLine(['M', x1, y1, 'L', x2, y2], lineWidth || 1);\n },\n\n /**\n * Internal function to et the tick positions of a linear axis to round\n * values like whole tens or every five.\n *\n * @param {Number} tickInterval\n * The normalized tick interval\n * @param {Number} min\n * Axis minimum.\n * @param {Number} max\n * Axis maximum.\n *\n * @return {Array.}\n * An array of numbers where ticks should be placed.\n */\n getLinearTickPositions: function(tickInterval, min, max) {\n var pos,\n lastPos,\n roundedMin = correctFloat(Math.floor(min / tickInterval) * tickInterval),\n roundedMax = correctFloat(Math.ceil(max / tickInterval) * tickInterval),\n tickPositions = [];\n\n // For single points, add a tick regardless of the relative position\n // (#2662, #6274)\n if (this.single) {\n return [min];\n }\n\n // Populate the intermediate values\n pos = roundedMin;\n while (pos <= roundedMax) {\n\n // Place the tick on the rounded value\n tickPositions.push(pos);\n\n // Always add the raw tickInterval, not the corrected one.\n pos = correctFloat(pos + tickInterval);\n\n // If the interval is not big enough in the current min - max range to actually increase\n // the loop variable, we need to break out to prevent endless loop. Issue #619\n if (pos === lastPos) {\n break;\n }\n\n // Record the last value\n lastPos = pos;\n }\n return tickPositions;\n },\n\n /**\n * Return the minor tick positions. For logarithmic axes, reuse the same logic\n * as for major ticks.\n */\n getMinorTickPositions: function() {\n var axis = this,\n options = axis.options,\n tickPositions = axis.tickPositions,\n minorTickInterval = axis.minorTickInterval,\n minorTickPositions = [],\n pos,\n pointRangePadding = axis.pointRangePadding || 0,\n min = axis.min - pointRangePadding, // #1498\n max = axis.max + pointRangePadding, // #1498\n range = max - min;\n\n // If minor ticks get too dense, they are hard to read, and may cause long running script. So we don't draw them.\n if (range && range / minorTickInterval < axis.len / 3) { // #3875\n\n if (axis.isLog) {\n // For each interval in the major ticks, compute the minor ticks\n // separately.\n each(this.paddedTicks, function(pos, i, paddedTicks) {\n if (i) {\n minorTickPositions.push.apply(\n minorTickPositions,\n axis.getLogTickPositions(\n minorTickInterval,\n paddedTicks[i - 1],\n paddedTicks[i],\n true\n )\n );\n }\n });\n\n } else if (axis.isDatetimeAxis && options.minorTickInterval === 'auto') { // #1314\n minorTickPositions = minorTickPositions.concat(\n axis.getTimeTicks(\n axis.normalizeTimeTickInterval(minorTickInterval),\n min,\n max,\n options.startOfWeek\n )\n );\n } else {\n for (\n pos = min + (tickPositions[0] - min) % minorTickInterval; pos <= max; pos += minorTickInterval\n ) {\n // Very, very, tight grid lines (#5771)\n if (pos === minorTickPositions[0]) {\n break;\n }\n minorTickPositions.push(pos);\n }\n }\n }\n\n if (minorTickPositions.length !== 0) {\n axis.trimTicks(minorTickPositions); // #3652 #3743 #1498 #6330\n }\n return minorTickPositions;\n },\n\n /**\n * Adjust the min and max for the minimum range. Keep in mind that the series data is\n * not yet processed, so we don't have information on data cropping and grouping, or\n * updated axis.pointRange or series.pointRange. The data can't be processed until\n * we have finally established min and max.\n *\n * @private\n */\n adjustForMinRange: function() {\n var axis = this,\n options = axis.options,\n min = axis.min,\n max = axis.max,\n zoomOffset,\n spaceAvailable,\n closestDataRange,\n i,\n distance,\n xData,\n loopLength,\n minArgs,\n maxArgs,\n minRange;\n\n // Set the automatic minimum range based on the closest point distance\n if (axis.isXAxis && axis.minRange === undefined && !axis.isLog) {\n\n if (defined(options.min) || defined(options.max)) {\n axis.minRange = null; // don't do this again\n\n } else {\n\n // Find the closest distance between raw data points, as opposed to\n // closestPointRange that applies to processed points (cropped and grouped)\n each(axis.series, function(series) {\n xData = series.xData;\n loopLength = series.xIncrement ? 1 : xData.length - 1;\n for (i = loopLength; i > 0; i--) {\n distance = xData[i] - xData[i - 1];\n if (closestDataRange === undefined || distance < closestDataRange) {\n closestDataRange = distance;\n }\n }\n });\n axis.minRange = Math.min(closestDataRange * 5, axis.dataMax - axis.dataMin);\n }\n }\n\n // if minRange is exceeded, adjust\n if (max - min < axis.minRange) {\n\n spaceAvailable = axis.dataMax - axis.dataMin >= axis.minRange;\n minRange = axis.minRange;\n zoomOffset = (minRange - max + min) / 2;\n\n // if min and max options have been set, don't go beyond it\n minArgs = [min - zoomOffset, pick(options.min, min - zoomOffset)];\n if (spaceAvailable) { // if space is available, stay within the data range\n minArgs[2] = axis.isLog ? axis.log2lin(axis.dataMin) : axis.dataMin;\n }\n min = arrayMax(minArgs);\n\n maxArgs = [min + minRange, pick(options.max, min + minRange)];\n if (spaceAvailable) { // if space is availabe, stay within the data range\n maxArgs[2] = axis.isLog ? axis.log2lin(axis.dataMax) : axis.dataMax;\n }\n\n max = arrayMin(maxArgs);\n\n // now if the max is adjusted, adjust the min back\n if (max - min < minRange) {\n minArgs[0] = max - minRange;\n minArgs[1] = pick(options.min, max - minRange);\n min = arrayMax(minArgs);\n }\n }\n\n // Record modified extremes\n axis.min = min;\n axis.max = max;\n },\n\n /**\n * Find the closestPointRange across all series.\n *\n * @private\n */\n getClosest: function() {\n var ret;\n\n if (this.categories) {\n ret = 1;\n } else {\n each(this.series, function(series) {\n var seriesClosest = series.closestPointRange,\n visible = series.visible ||\n !series.chart.options.chart.ignoreHiddenSeries;\n\n if (!series.noSharedTooltip &&\n defined(seriesClosest) &&\n visible\n ) {\n ret = defined(ret) ?\n Math.min(ret, seriesClosest) :\n seriesClosest;\n }\n });\n }\n return ret;\n },\n\n /**\n * When a point name is given and no x, search for the name in the existing categories,\n * or if categories aren't provided, search names or create a new category (#2522).\n */\n nameToX: function(point) {\n var explicitCategories = isArray(this.categories),\n names = explicitCategories ? this.categories : this.names,\n nameX = point.options.x,\n x;\n\n point.series.requireSorting = false;\n\n if (!defined(nameX)) {\n nameX = this.options.uniqueNames === false ?\n point.series.autoIncrement() :\n inArray(point.name, names);\n }\n if (nameX === -1) { // The name is not found in currenct categories\n if (!explicitCategories) {\n x = names.length;\n }\n } else {\n x = nameX;\n }\n\n // Write the last point's name to the names array\n if (x !== undefined) {\n this.names[x] = point.name;\n }\n\n return x;\n },\n\n /**\n * When changes have been done to series data, update the axis.names.\n */\n updateNames: function() {\n var axis = this;\n\n if (this.names.length > 0) {\n this.names.length = 0;\n this.minRange = this.userMinRange; // Reset\n each(this.series || [], function(series) {\n\n // Reset incrementer (#5928)\n series.xIncrement = null;\n\n // When adding a series, points are not yet generated\n if (!series.points || series.isDirtyData) {\n series.processData();\n series.generatePoints();\n }\n\n each(series.points, function(point, i) {\n var x;\n if (point.options) {\n x = axis.nameToX(point);\n if (x !== undefined && x !== point.x) {\n point.x = x;\n series.xData[i] = x;\n }\n }\n });\n });\n }\n },\n\n /**\n * Update translation information\n */\n setAxisTranslation: function(saveOld) {\n var axis = this,\n range = axis.max - axis.min,\n pointRange = axis.axisPointRange || 0,\n closestPointRange,\n minPointOffset = 0,\n pointRangePadding = 0,\n linkedParent = axis.linkedParent,\n ordinalCorrection,\n hasCategories = !!axis.categories,\n transA = axis.transA,\n isXAxis = axis.isXAxis;\n\n // Adjust translation for padding. Y axis with categories need to go through the same (#1784).\n if (isXAxis || hasCategories || pointRange) {\n\n // Get the closest points\n closestPointRange = axis.getClosest();\n\n if (linkedParent) {\n minPointOffset = linkedParent.minPointOffset;\n pointRangePadding = linkedParent.pointRangePadding;\n } else {\n each(axis.series, function(series) {\n var seriesPointRange = hasCategories ?\n 1 :\n (isXAxis ?\n pick(series.options.pointRange, closestPointRange, 0) :\n (axis.axisPointRange || 0)), // #2806\n pointPlacement = series.options.pointPlacement;\n\n pointRange = Math.max(pointRange, seriesPointRange);\n\n if (!axis.single) {\n // minPointOffset is the value padding to the left of the axis in order to make\n // room for points with a pointRange, typically columns. When the pointPlacement option\n // is 'between' or 'on', this padding does not apply.\n minPointOffset = Math.max(\n minPointOffset,\n isString(pointPlacement) ? 0 : seriesPointRange / 2\n );\n\n // Determine the total padding needed to the length of the axis to make room for the\n // pointRange. If the series' pointPlacement is 'on', no padding is added.\n pointRangePadding = Math.max(\n pointRangePadding,\n pointPlacement === 'on' ? 0 : seriesPointRange\n );\n }\n });\n }\n\n // Record minPointOffset and pointRangePadding\n ordinalCorrection = axis.ordinalSlope && closestPointRange ? axis.ordinalSlope / closestPointRange : 1; // #988, #1853\n axis.minPointOffset = minPointOffset = minPointOffset * ordinalCorrection;\n axis.pointRangePadding = pointRangePadding = pointRangePadding * ordinalCorrection;\n\n // pointRange means the width reserved for each point, like in a column chart\n axis.pointRange = Math.min(pointRange, range);\n\n // closestPointRange means the closest distance between points. In columns\n // it is mostly equal to pointRange, but in lines pointRange is 0 while closestPointRange\n // is some other value\n if (isXAxis) {\n axis.closestPointRange = closestPointRange;\n }\n }\n\n // Secondary values\n if (saveOld) {\n axis.oldTransA = transA;\n }\n axis.translationSlope = axis.transA = transA =\n axis.options.staticScale ||\n axis.len / ((range + pointRangePadding) || 1);\n axis.transB = axis.horiz ? axis.left : axis.bottom; // translation addend\n axis.minPixelPadding = transA * minPointOffset;\n },\n\n minFromRange: function() {\n return this.max - this.range;\n },\n\n /**\n * Set the tick positions to round values and optionally extend the extremes\n * to the nearest tick\n */\n setTickInterval: function(secondPass) {\n var axis = this,\n chart = axis.chart,\n options = axis.options,\n isLog = axis.isLog,\n log2lin = axis.log2lin,\n isDatetimeAxis = axis.isDatetimeAxis,\n isXAxis = axis.isXAxis,\n isLinked = axis.isLinked,\n maxPadding = options.maxPadding,\n minPadding = options.minPadding,\n length,\n linkedParentExtremes,\n tickIntervalOption = options.tickInterval,\n minTickInterval,\n tickPixelIntervalOption = options.tickPixelInterval,\n categories = axis.categories,\n threshold = axis.threshold,\n softThreshold = axis.softThreshold,\n thresholdMin,\n thresholdMax,\n hardMin,\n hardMax;\n\n if (!isDatetimeAxis && !categories && !isLinked) {\n this.getTickAmount();\n }\n\n // Min or max set either by zooming/setExtremes or initial options\n hardMin = pick(axis.userMin, options.min);\n hardMax = pick(axis.userMax, options.max);\n\n // Linked axis gets the extremes from the parent axis\n if (isLinked) {\n axis.linkedParent = chart[axis.coll][options.linkedTo];\n linkedParentExtremes = axis.linkedParent.getExtremes();\n axis.min = pick(linkedParentExtremes.min, linkedParentExtremes.dataMin);\n axis.max = pick(linkedParentExtremes.max, linkedParentExtremes.dataMax);\n if (options.type !== axis.linkedParent.options.type) {\n H.error(11, 1); // Can't link axes of different type\n }\n\n // Initial min and max from the extreme data values\n } else {\n\n // Adjust to hard threshold\n if (!softThreshold && defined(threshold)) {\n if (axis.dataMin >= threshold) {\n thresholdMin = threshold;\n minPadding = 0;\n } else if (axis.dataMax <= threshold) {\n thresholdMax = threshold;\n maxPadding = 0;\n }\n }\n\n axis.min = pick(hardMin, thresholdMin, axis.dataMin);\n axis.max = pick(hardMax, thresholdMax, axis.dataMax);\n\n }\n\n if (isLog) {\n if (\n axis.positiveValuesOnly &&\n !secondPass &&\n Math.min(axis.min, pick(axis.dataMin, axis.min)) <= 0\n ) { // #978\n H.error(10, 1); // Can't plot negative values on log axis\n }\n // The correctFloat cures #934, float errors on full tens. But it\n // was too aggressive for #4360 because of conversion back to lin,\n // therefore use precision 15.\n axis.min = correctFloat(log2lin(axis.min), 15);\n axis.max = correctFloat(log2lin(axis.max), 15);\n }\n\n // handle zoomed range\n if (axis.range && defined(axis.max)) {\n axis.userMin = axis.min = hardMin = Math.max(axis.min, axis.minFromRange()); // #618\n axis.userMax = hardMax = axis.max;\n\n axis.range = null; // don't use it when running setExtremes\n }\n\n // Hook for Highstock Scroller. Consider combining with beforePadding.\n fireEvent(axis, 'foundExtremes');\n\n // Hook for adjusting this.min and this.max. Used by bubble series.\n if (axis.beforePadding) {\n axis.beforePadding();\n }\n\n // adjust min and max for the minimum range\n axis.adjustForMinRange();\n\n // Pad the values to get clear of the chart's edges. To avoid tickInterval taking the padding\n // into account, we do this after computing tick interval (#1337).\n if (!categories && !axis.axisPointRange && !axis.usePercentage && !isLinked && defined(axis.min) && defined(axis.max)) {\n length = axis.max - axis.min;\n if (length) {\n if (!defined(hardMin) && minPadding) {\n axis.min -= length * minPadding;\n }\n if (!defined(hardMax) && maxPadding) {\n axis.max += length * maxPadding;\n }\n }\n }\n\n // Handle options for floor, ceiling, softMin and softMax (#6359)\n if (isNumber(options.softMin)) {\n axis.min = Math.min(axis.min, options.softMin);\n }\n if (isNumber(options.softMax)) {\n axis.max = Math.max(axis.max, options.softMax);\n }\n if (isNumber(options.floor)) {\n axis.min = Math.max(axis.min, options.floor);\n }\n if (isNumber(options.ceiling)) {\n axis.max = Math.min(axis.max, options.ceiling);\n }\n\n\n // When the threshold is soft, adjust the extreme value only if\n // the data extreme and the padded extreme land on either side of the threshold. For example,\n // a series of [0, 1, 2, 3] would make the yAxis add a tick for -1 because of the\n // default minPadding and startOnTick options. This is prevented by the softThreshold\n // option.\n if (softThreshold && defined(axis.dataMin)) {\n threshold = threshold || 0;\n if (!defined(hardMin) && axis.min < threshold && axis.dataMin >= threshold) {\n axis.min = threshold;\n } else if (!defined(hardMax) && axis.max > threshold && axis.dataMax <= threshold) {\n axis.max = threshold;\n }\n }\n\n\n // get tickInterval\n if (axis.min === axis.max || axis.min === undefined || axis.max === undefined) {\n axis.tickInterval = 1;\n } else if (isLinked && !tickIntervalOption &&\n tickPixelIntervalOption === axis.linkedParent.options.tickPixelInterval) {\n axis.tickInterval = tickIntervalOption = axis.linkedParent.tickInterval;\n } else {\n axis.tickInterval = pick(\n tickIntervalOption,\n this.tickAmount ? ((axis.max - axis.min) / Math.max(this.tickAmount - 1, 1)) : undefined,\n categories ? // for categoried axis, 1 is default, for linear axis use tickPix\n 1 :\n // don't let it be more than the data range\n (axis.max - axis.min) * tickPixelIntervalOption / Math.max(axis.len, tickPixelIntervalOption)\n );\n }\n\n // Now we're finished detecting min and max, crop and group series data. This\n // is in turn needed in order to find tick positions in ordinal axes.\n if (isXAxis && !secondPass) {\n each(axis.series, function(series) {\n series.processData(axis.min !== axis.oldMin || axis.max !== axis.oldMax);\n });\n }\n\n // set the translation factor used in translate function\n axis.setAxisTranslation(true);\n\n // hook for ordinal axes and radial axes\n if (axis.beforeSetTickPositions) {\n axis.beforeSetTickPositions();\n }\n\n // hook for extensions, used in Highstock ordinal axes\n if (axis.postProcessTickInterval) {\n axis.tickInterval = axis.postProcessTickInterval(axis.tickInterval);\n }\n\n // In column-like charts, don't cramp in more ticks than there are points (#1943, #4184)\n if (axis.pointRange && !tickIntervalOption) {\n axis.tickInterval = Math.max(axis.pointRange, axis.tickInterval);\n }\n\n // Before normalizing the tick interval, handle minimum tick interval. This applies only if tickInterval is not defined.\n minTickInterval = pick(options.minTickInterval, axis.isDatetimeAxis && axis.closestPointRange);\n if (!tickIntervalOption && axis.tickInterval < minTickInterval) {\n axis.tickInterval = minTickInterval;\n }\n\n // for linear axes, get magnitude and normalize the interval\n if (!isDatetimeAxis && !isLog && !tickIntervalOption) {\n axis.tickInterval = normalizeTickInterval(\n axis.tickInterval,\n null,\n getMagnitude(axis.tickInterval),\n // If the tick interval is between 0.5 and 5 and the axis max is in the order of\n // thousands, chances are we are dealing with years. Don't allow decimals. #3363.\n pick(options.allowDecimals, !(axis.tickInterval > 0.5 && axis.tickInterval < 5 && axis.max > 1000 && axis.max < 9999)), !!this.tickAmount\n );\n }\n\n // Prevent ticks from getting so close that we can't draw the labels\n if (!this.tickAmount) {\n axis.tickInterval = axis.unsquish();\n }\n\n this.setTickPositions();\n },\n\n /**\n * Now we have computed the normalized tickInterval, get the tick positions\n */\n setTickPositions: function() {\n\n var options = this.options,\n tickPositions,\n tickPositionsOption = options.tickPositions,\n tickPositioner = options.tickPositioner,\n startOnTick = options.startOnTick,\n endOnTick = options.endOnTick;\n\n // Set the tickmarkOffset\n this.tickmarkOffset = (this.categories && options.tickmarkPlacement === 'between' &&\n this.tickInterval === 1) ? 0.5 : 0; // #3202\n\n\n // get minorTickInterval\n this.minorTickInterval = options.minorTickInterval === 'auto' && this.tickInterval ?\n this.tickInterval / 5 : options.minorTickInterval;\n\n // When there is only one point, or all points have the same value on\n // this axis, then min and max are equal and tickPositions.length is 0\n // or 1. In this case, add some padding in order to center the point,\n // but leave it with one tick. #1337.\n this.single =\n this.min === this.max &&\n defined(this.min) &&\n !this.tickAmount &&\n (\n // Data is on integer (#6563)\n parseInt(this.min, 10) === this.min ||\n\n // Between integers and decimals are not allowed (#6274)\n options.allowDecimals !== false\n );\n\n // Find the tick positions\n this.tickPositions = tickPositions = tickPositionsOption && tickPositionsOption.slice(); // Work on a copy (#1565)\n if (!tickPositions) {\n\n if (this.isDatetimeAxis) {\n tickPositions = this.getTimeTicks(\n this.normalizeTimeTickInterval(\n this.tickInterval,\n options.units\n ),\n this.min,\n this.max,\n options.startOfWeek,\n this.ordinalPositions,\n this.closestPointRange,\n true\n );\n } else if (this.isLog) {\n tickPositions = this.getLogTickPositions(\n this.tickInterval,\n this.min,\n this.max\n );\n } else {\n tickPositions = this.getLinearTickPositions(\n this.tickInterval,\n this.min,\n this.max\n );\n }\n\n // Too dense ticks, keep only the first and last (#4477)\n if (tickPositions.length > this.len) {\n tickPositions = [tickPositions[0], tickPositions.pop()];\n }\n\n this.tickPositions = tickPositions;\n\n // Run the tick positioner callback, that allows modifying auto tick positions.\n if (tickPositioner) {\n tickPositioner = tickPositioner.apply(this, [this.min, this.max]);\n if (tickPositioner) {\n this.tickPositions = tickPositions = tickPositioner;\n }\n }\n\n }\n\n // Reset min/max or remove extremes based on start/end on tick\n this.paddedTicks = tickPositions.slice(0); // Used for logarithmic minor\n this.trimTicks(tickPositions, startOnTick, endOnTick);\n if (!this.isLinked) {\n\n // Substract half a unit (#2619, #2846, #2515, #3390)\n if (this.single) {\n this.min -= 0.5;\n this.max += 0.5;\n }\n if (!tickPositionsOption && !tickPositioner) {\n this.adjustTickAmount();\n }\n }\n },\n\n /**\n * Handle startOnTick and endOnTick by either adapting to padding min/max or rounded min/max\n */\n trimTicks: function(tickPositions, startOnTick, endOnTick) {\n var roundedMin = tickPositions[0],\n roundedMax = tickPositions[tickPositions.length - 1],\n minPointOffset = this.minPointOffset || 0;\n\n if (!this.isLinked) {\n if (startOnTick && roundedMin !== -Infinity) { // #6502\n this.min = roundedMin;\n } else {\n while (this.min - minPointOffset > tickPositions[0]) {\n tickPositions.shift();\n }\n }\n\n if (endOnTick) {\n this.max = roundedMax;\n } else {\n while (this.max + minPointOffset < tickPositions[tickPositions.length - 1]) {\n tickPositions.pop();\n }\n }\n\n // If no tick are left, set one tick in the middle (#3195)\n if (tickPositions.length === 0 && defined(roundedMin)) {\n tickPositions.push((roundedMax + roundedMin) / 2);\n }\n }\n },\n\n /**\n * Check if there are multiple axes in the same pane.\n *\n * @private\n * @return {Boolean}\n * True if there are other axes.\n */\n alignToOthers: function() {\n var others = {}, // Whether there is another axis to pair with this one\n hasOther,\n options = this.options;\n\n if (\n // Only if alignTicks is true\n this.chart.options.chart.alignTicks !== false &&\n options.alignTicks !== false &&\n\n // Don't try to align ticks on a log axis, they are not evenly\n // spaced (#6021)\n !this.isLog\n ) {\n each(this.chart[this.coll], function(axis) {\n var otherOptions = axis.options,\n horiz = axis.horiz,\n key = [\n horiz ? otherOptions.left : otherOptions.top,\n otherOptions.width,\n otherOptions.height,\n otherOptions.pane\n ].join(',');\n\n\n if (axis.series.length) { // #4442\n if (others[key]) {\n hasOther = true; // #4201\n } else {\n others[key] = 1;\n }\n }\n });\n }\n return hasOther;\n },\n\n /**\n * Set the max ticks of either the x and y axis collection\n */\n getTickAmount: function() {\n var options = this.options,\n tickAmount = options.tickAmount,\n tickPixelInterval = options.tickPixelInterval;\n\n if (!defined(options.tickInterval) && this.len < tickPixelInterval && !this.isRadial &&\n !this.isLog && options.startOnTick && options.endOnTick) {\n tickAmount = 2;\n }\n\n if (!tickAmount && this.alignToOthers()) {\n // Add 1 because 4 tick intervals require 5 ticks (including first and last)\n tickAmount = Math.ceil(this.len / tickPixelInterval) + 1;\n }\n\n // For tick amounts of 2 and 3, compute five ticks and remove the intermediate ones. This\n // prevents the axis from adding ticks that are too far away from the data extremes.\n if (tickAmount < 4) {\n this.finalTickAmt = tickAmount;\n tickAmount = 5;\n }\n\n this.tickAmount = tickAmount;\n },\n\n /**\n * When using multiple axes, adjust the number of ticks to match the highest\n * number of ticks in that group.\n *\n * @private\n */\n adjustTickAmount: function() {\n var tickInterval = this.tickInterval,\n tickPositions = this.tickPositions,\n tickAmount = this.tickAmount,\n finalTickAmt = this.finalTickAmt,\n currentTickAmount = tickPositions && tickPositions.length,\n i,\n len;\n\n if (currentTickAmount < tickAmount) {\n while (tickPositions.length < tickAmount) {\n tickPositions.push(correctFloat(\n tickPositions[tickPositions.length - 1] + tickInterval\n ));\n }\n this.transA *= (currentTickAmount - 1) / (tickAmount - 1);\n this.max = tickPositions[tickPositions.length - 1];\n\n // We have too many ticks, run second pass to try to reduce ticks\n } else if (currentTickAmount > tickAmount) {\n this.tickInterval *= 2;\n this.setTickPositions();\n }\n\n // The finalTickAmt property is set in getTickAmount\n if (defined(finalTickAmt)) {\n i = len = tickPositions.length;\n while (i--) {\n if (\n (finalTickAmt === 3 && i % 2 === 1) || // Remove every other tick\n (finalTickAmt <= 2 && i > 0 && i < len - 1) // Remove all but first and last\n ) {\n tickPositions.splice(i, 1);\n }\n }\n this.finalTickAmt = undefined;\n }\n },\n\n /**\n * Set the scale based on data min and max, user set min and max or options\n *\n */\n setScale: function() {\n var axis = this,\n isDirtyData,\n isDirtyAxisLength;\n\n axis.oldMin = axis.min;\n axis.oldMax = axis.max;\n axis.oldAxisLength = axis.len;\n\n // set the new axisLength\n axis.setAxisSize();\n //axisLength = horiz ? axisWidth : axisHeight;\n isDirtyAxisLength = axis.len !== axis.oldAxisLength;\n\n // is there new data?\n each(axis.series, function(series) {\n if (series.isDirtyData || series.isDirty ||\n series.xAxis.isDirty) { // when x axis is dirty, we need new data extremes for y as well\n isDirtyData = true;\n }\n });\n\n // do we really need to go through all this?\n if (isDirtyAxisLength || isDirtyData || axis.isLinked || axis.forceRedraw ||\n axis.userMin !== axis.oldUserMin || axis.userMax !== axis.oldUserMax || axis.alignToOthers()) {\n\n if (axis.resetStacks) {\n axis.resetStacks();\n }\n\n axis.forceRedraw = false;\n\n // get data extremes if needed\n axis.getSeriesExtremes();\n\n // get fixed positions based on tickInterval\n axis.setTickInterval();\n\n // record old values to decide whether a rescale is necessary later on (#540)\n axis.oldUserMin = axis.userMin;\n axis.oldUserMax = axis.userMax;\n\n // Mark as dirty if it is not already set to dirty and extremes have changed. #595.\n if (!axis.isDirty) {\n axis.isDirty = isDirtyAxisLength || axis.min !== axis.oldMin || axis.max !== axis.oldMax;\n }\n } else if (axis.cleanStacks) {\n axis.cleanStacks();\n }\n },\n\n /**\n * Set the minimum and maximum of the axes after render time. If the\n * `startOnTick` and `endOnTick` options are true, the minimum and maximum\n * values are rounded off to the nearest tick. To prevent this, these\n * options can be set to false before calling setExtremes. Also, setExtremes\n * will not allow a range lower than the `minRange` option, which by default\n * is the range of five points.\n * \n * @param {Number} [newMin]\n * The new minimum value.\n * @param {Number} [newMax]\n * The new maximum value.\n * @param {Boolean} [redraw=true]\n * Whether to redraw the chart or wait for an explicit call to \n * {@link Highcharts.Chart#redraw}\n * @param {AnimationOptions} [animation=true]\n * Enable or modify animations.\n * @param {Object} [eventArguments]\n * Arguments to be accessed in event handler.\n *\n * @sample highcharts/members/axis-setextremes/\n * Set extremes from a button\n * @sample highcharts/members/axis-setextremes-datetime/\n * Set extremes on a datetime axis\n * @sample highcharts/members/axis-setextremes-off-ticks/\n * Set extremes off ticks\n * @sample stock/members/axis-setextremes/\n * Set extremes in Highstock\n * @sample maps/members/axis-setextremes/\n * Set extremes in Highmaps\n */\n setExtremes: function(newMin, newMax, redraw, animation, eventArguments) {\n var axis = this,\n chart = axis.chart;\n\n redraw = pick(redraw, true); // defaults to true\n\n each(axis.series, function(serie) {\n delete serie.kdTree;\n });\n\n // Extend the arguments with min and max\n eventArguments = extend(eventArguments, {\n min: newMin,\n max: newMax\n });\n\n // Fire the event\n fireEvent(axis, 'setExtremes', eventArguments, function() { // the default event handler\n\n axis.userMin = newMin;\n axis.userMax = newMax;\n axis.eventArgs = eventArguments;\n\n if (redraw) {\n chart.redraw(animation);\n }\n });\n },\n\n /**\n * Overridable method for zooming chart. Pulled out in a separate method to allow overriding\n * in stock charts.\n */\n zoom: function(newMin, newMax) {\n var dataMin = this.dataMin,\n dataMax = this.dataMax,\n options = this.options,\n min = Math.min(dataMin, pick(options.min, dataMin)),\n max = Math.max(dataMax, pick(options.max, dataMax));\n\n if (newMin !== this.min || newMax !== this.max) { // #5790\n\n // Prevent pinch zooming out of range. Check for defined is for #1946. #1734.\n if (!this.allowZoomOutside) {\n // #6014, sometimes newMax will be smaller than min (or newMin will be larger than max).\n if (defined(dataMin)) {\n if (newMin < min) {\n newMin = min;\n }\n if (newMin > max) {\n newMin = max;\n }\n }\n if (defined(dataMax)) {\n if (newMax < min) {\n newMax = min;\n }\n if (newMax > max) {\n newMax = max;\n }\n }\n }\n\n // In full view, displaying the reset zoom button is not required\n this.displayBtn = newMin !== undefined || newMax !== undefined;\n\n // Do it\n this.setExtremes(\n newMin,\n newMax,\n false,\n undefined, {\n trigger: 'zoom'\n }\n );\n }\n\n return true;\n },\n\n /**\n * Update the axis metrics\n */\n setAxisSize: function() {\n var chart = this.chart,\n options = this.options,\n offsets = options.offsets || [0, 0, 0, 0], // top / right / bottom / left\n horiz = this.horiz,\n width = pick(options.width, chart.plotWidth - offsets[3] + offsets[1]),\n height = pick(options.height, chart.plotHeight - offsets[0] + offsets[2]),\n top = pick(options.top, chart.plotTop + offsets[0]),\n left = pick(options.left, chart.plotLeft + offsets[3]),\n percentRegex = /%$/;\n\n // Check for percentage based input values. Rounding fixes problems with\n // column overflow and plot line filtering (#4898, #4899)\n if (percentRegex.test(height)) {\n height = Math.round(parseFloat(height) / 100 * chart.plotHeight);\n }\n if (percentRegex.test(top)) {\n top = Math.round(parseFloat(top) / 100 * chart.plotHeight + chart.plotTop);\n }\n\n // Expose basic values to use in Series object and navigator\n this.left = left;\n this.top = top;\n this.width = width;\n this.height = height;\n this.bottom = chart.chartHeight - height - top;\n this.right = chart.chartWidth - width - left;\n\n // Direction agnostic properties\n this.len = Math.max(horiz ? width : height, 0); // Math.max fixes #905\n this.pos = horiz ? left : top; // distance from SVG origin\n },\n\n /**\n * The returned object literal from the {@link Highcharts.Axis#getExtremes}\n * function. \n * @typedef {Object} Extremes\n * @property {Number} dataMax\n * The maximum value of the axis' associated series.\n * @property {Number} dataMin\n * The minimum value of the axis' associated series.\n * @property {Number} max\n * The maximum axis value, either automatic or set manually. If the\n * `max` option is not set, `maxPadding` is 0 and `endOnTick` is\n * false, this value will be the same as `dataMax`.\n * @property {Number} min\n * The minimum axis value, either automatic or set manually. If the\n * `min` option is not set, `minPadding` is 0 and `startOnTick` is\n * false, this value will be the same as `dataMin`.\n */\n /**\n * Get the current extremes for the axis.\n *\n * @returns {Extremes}\n * An object containing extremes information.\n * \n * @sample members/axis-getextremes/\n * Report extremes by click on a button\n * @sample maps/members/axis-getextremes/\n * Get extremes in Highmaps\n */\n getExtremes: function() {\n var axis = this,\n isLog = axis.isLog,\n lin2log = axis.lin2log;\n\n return {\n min: isLog ? correctFloat(lin2log(axis.min)) : axis.min,\n max: isLog ? correctFloat(lin2log(axis.max)) : axis.max,\n dataMin: axis.dataMin,\n dataMax: axis.dataMax,\n userMin: axis.userMin,\n userMax: axis.userMax\n };\n },\n\n /**\n * Get the zero plane either based on zero or on the min or max value.\n * Used in bar and area plots\n */\n getThreshold: function(threshold) {\n var axis = this,\n isLog = axis.isLog,\n lin2log = axis.lin2log,\n realMin = isLog ? lin2log(axis.min) : axis.min,\n realMax = isLog ? lin2log(axis.max) : axis.max;\n\n if (threshold === null) {\n threshold = realMin;\n } else if (realMin > threshold) {\n threshold = realMin;\n } else if (realMax < threshold) {\n threshold = realMax;\n }\n\n return axis.translate(threshold, 0, 1, 0, 1);\n },\n\n /**\n * Compute auto alignment for the axis label based on which side the axis is\n * on and the given rotation for the label.\n *\n * @param {Number} rotation\n * The rotation in degrees as set by either the `rotation` or \n * `autoRotation` options.\n * @private\n */\n autoLabelAlign: function(rotation) {\n var ret,\n angle = (pick(rotation, 0) - (this.side * 90) + 720) % 360;\n\n if (angle > 15 && angle < 165) {\n ret = 'right';\n } else if (angle > 195 && angle < 345) {\n ret = 'left';\n } else {\n ret = 'center';\n }\n return ret;\n },\n\n /**\n * Get the tick length and width for the axis.\n * @param {String} prefix 'tick' or 'minorTick'\n * @returns {Array} An array of tickLength and tickWidth\n */\n tickSize: function(prefix) {\n var options = this.options,\n tickLength = options[prefix + 'Length'],\n tickWidth = pick(options[prefix + 'Width'], prefix === 'tick' && this.isXAxis ? 1 : 0); // X axis defaults to 1\n\n if (tickWidth && tickLength) {\n // Negate the length\n if (options[prefix + 'Position'] === 'inside') {\n tickLength = -tickLength;\n }\n return [tickLength, tickWidth];\n }\n\n },\n\n /**\n * Return the size of the labels\n */\n labelMetrics: function() {\n var index = this.tickPositions && this.tickPositions[0] || 0;\n return this.chart.renderer.fontMetrics(\n this.options.labels.style && this.options.labels.style.fontSize,\n this.ticks[index] && this.ticks[index].label\n );\n },\n\n /**\n * Prevent the ticks from getting so close we can't draw the labels. On a horizontal\n * axis, this is handled by rotating the labels, removing ticks and adding ellipsis.\n * On a vertical axis remove ticks and add ellipsis.\n */\n unsquish: function() {\n var labelOptions = this.options.labels,\n horiz = this.horiz,\n tickInterval = this.tickInterval,\n newTickInterval = tickInterval,\n slotSize = this.len / (((this.categories ? 1 : 0) + this.max - this.min) / tickInterval),\n rotation,\n rotationOption = labelOptions.rotation,\n labelMetrics = this.labelMetrics(),\n step,\n bestScore = Number.MAX_VALUE,\n autoRotation,\n // Return the multiple of tickInterval that is needed to avoid collision\n getStep = function(spaceNeeded) {\n var step = spaceNeeded / (slotSize || 1);\n step = step > 1 ? Math.ceil(step) : 1;\n return step * tickInterval;\n };\n\n if (horiz) {\n autoRotation = !labelOptions.staggerLines && !labelOptions.step && ( // #3971\n defined(rotationOption) ? [rotationOption] :\n slotSize < pick(labelOptions.autoRotationLimit, 80) && labelOptions.autoRotation\n );\n\n if (autoRotation) {\n\n // Loop over the given autoRotation options, and determine which gives the best score. The\n // best score is that with the lowest number of steps and a rotation closest to horizontal.\n each(autoRotation, function(rot) {\n var score;\n\n if (rot === rotationOption || (rot && rot >= -90 && rot <= 90)) { // #3891\n\n step = getStep(Math.abs(labelMetrics.h / Math.sin(deg2rad * rot)));\n\n score = step + Math.abs(rot / 360);\n\n if (score < bestScore) {\n bestScore = score;\n rotation = rot;\n newTickInterval = step;\n }\n }\n });\n }\n\n } else if (!labelOptions.step) { // #4411\n newTickInterval = getStep(labelMetrics.h);\n }\n\n this.autoRotation = autoRotation;\n this.labelRotation = pick(rotation, rotationOption);\n\n return newTickInterval;\n },\n\n /**\n * Get the general slot width for this axis. This may change between the pre-render (from Axis.getOffset) \n * and the final tick rendering and placement (#5086).\n */\n getSlotWidth: function() {\n var chart = this.chart,\n horiz = this.horiz,\n labelOptions = this.options.labels,\n slotCount = Math.max(this.tickPositions.length - (this.categories ? 0 : 1), 1),\n marginLeft = chart.margin[3];\n\n return (\n horiz &&\n (labelOptions.step || 0) < 2 &&\n !labelOptions.rotation && // #4415\n ((this.staggerLines || 1) * this.len) / slotCount\n ) || (!horiz && (\n (marginLeft && (marginLeft - chart.spacing[3])) ||\n chart.chartWidth * 0.33\n )); // #1580, #1931\n\n },\n\n /**\n * Render the axis labels and determine whether ellipsis or rotation need to be applied\n */\n renderUnsquish: function() {\n var chart = this.chart,\n renderer = chart.renderer,\n tickPositions = this.tickPositions,\n ticks = this.ticks,\n labelOptions = this.options.labels,\n horiz = this.horiz,\n slotWidth = this.getSlotWidth(),\n innerWidth = Math.max(1, Math.round(slotWidth - 2 * (labelOptions.padding || 5))),\n attr = {},\n labelMetrics = this.labelMetrics(),\n textOverflowOption = labelOptions.style && labelOptions.style.textOverflow,\n css,\n maxLabelLength = 0,\n label,\n i,\n pos;\n\n // Set rotation option unless it is \"auto\", like in gauges\n if (!isString(labelOptions.rotation)) {\n attr.rotation = labelOptions.rotation || 0; // #4443\n }\n\n // Get the longest label length\n each(tickPositions, function(tick) {\n tick = ticks[tick];\n if (tick && tick.labelLength > maxLabelLength) {\n maxLabelLength = tick.labelLength;\n }\n });\n this.maxLabelLength = maxLabelLength;\n\n\n // Handle auto rotation on horizontal axis\n if (this.autoRotation) {\n\n // Apply rotation only if the label is too wide for the slot, and\n // the label is wider than its height.\n if (maxLabelLength > innerWidth && maxLabelLength > labelMetrics.h) {\n attr.rotation = this.labelRotation;\n } else {\n this.labelRotation = 0;\n }\n\n // Handle word-wrap or ellipsis on vertical axis\n } else if (slotWidth) {\n // For word-wrap or ellipsis\n css = {\n width: innerWidth + 'px'\n };\n\n if (!textOverflowOption) {\n css.textOverflow = 'clip';\n\n // On vertical axis, only allow word wrap if there is room for more lines.\n i = tickPositions.length;\n while (!horiz && i--) {\n pos = tickPositions[i];\n label = ticks[pos].label;\n if (label) {\n // Reset ellipsis in order to get the correct bounding box (#4070)\n if (label.styles && label.styles.textOverflow === 'ellipsis') {\n label.css({\n textOverflow: 'clip'\n });\n\n // Set the correct width in order to read the bounding box height (#4678, #5034)\n } else if (ticks[pos].labelLength > slotWidth) {\n label.css({\n width: slotWidth + 'px'\n });\n }\n\n if (label.getBBox().height > this.len / tickPositions.length - (labelMetrics.h - labelMetrics.f)) {\n label.specCss = {\n textOverflow: 'ellipsis'\n };\n }\n }\n }\n }\n }\n\n\n // Add ellipsis if the label length is significantly longer than ideal\n if (attr.rotation) {\n css = {\n width: (maxLabelLength > chart.chartHeight * 0.5 ? chart.chartHeight * 0.33 : chart.chartHeight) + 'px'\n };\n if (!textOverflowOption) {\n css.textOverflow = 'ellipsis';\n }\n }\n\n // Set the explicit or automatic label alignment\n this.labelAlign = labelOptions.align || this.autoLabelAlign(this.labelRotation);\n if (this.labelAlign) {\n attr.align = this.labelAlign;\n }\n\n // Apply general and specific CSS\n each(tickPositions, function(pos) {\n var tick = ticks[pos],\n label = tick && tick.label;\n if (label) {\n label.attr(attr); // This needs to go before the CSS in old IE (#4502)\n if (css) {\n label.css(merge(css, label.specCss));\n }\n delete label.specCss;\n tick.rotation = attr.rotation;\n }\n });\n\n // Note: Why is this not part of getLabelPosition?\n this.tickRotCorr = renderer.rotCorr(labelMetrics.b, this.labelRotation || 0, this.side !== 0);\n },\n\n /**\n * Return true if the axis has associated data\n */\n hasData: function() {\n return this.hasVisibleSeries || (defined(this.min) && defined(this.max) && !!this.tickPositions);\n },\n\n /**\n * Adds the title defined in axis.options.title.\n * @param {Boolean} display - whether or not to display the title\n */\n addTitle: function(display) {\n var axis = this,\n renderer = axis.chart.renderer,\n horiz = axis.horiz,\n opposite = axis.opposite,\n options = axis.options,\n axisTitleOptions = options.title,\n textAlign;\n\n if (!axis.axisTitle) {\n textAlign = axisTitleOptions.textAlign;\n if (!textAlign) {\n textAlign = (horiz ? {\n low: 'left',\n middle: 'center',\n high: 'right'\n } : {\n low: opposite ? 'right' : 'left',\n middle: 'center',\n high: opposite ? 'left' : 'right'\n })[axisTitleOptions.align];\n }\n axis.axisTitle = renderer.text(\n axisTitleOptions.text,\n 0,\n 0,\n axisTitleOptions.useHTML\n )\n .attr({\n zIndex: 7,\n rotation: axisTitleOptions.rotation || 0,\n align: textAlign\n })\n .addClass('highcharts-axis-title')\n\n .css(axisTitleOptions.style)\n\n .add(axis.axisGroup);\n axis.axisTitle.isNew = true;\n }\n\n // hide or show the title depending on whether showEmpty is set\n axis.axisTitle[display ? 'show' : 'hide'](true);\n },\n\n /**\n * Generates a tick for initial positioning.\n *\n * @private\n * @param {number} pos\n * The tick position in axis values.\n * @param {number} i\n * The index of the tick in {@link Axis.tickPositions}.\n */\n generateTick: function(pos) {\n var ticks = this.ticks;\n\n if (!ticks[pos]) {\n ticks[pos] = new Tick(this, pos);\n } else {\n ticks[pos].addLabel(); // update labels depending on tick interval\n }\n },\n\n /**\n * Render the tick labels to a preliminary position to get their sizes\n */\n getOffset: function() {\n var axis = this,\n chart = axis.chart,\n renderer = chart.renderer,\n options = axis.options,\n tickPositions = axis.tickPositions,\n ticks = axis.ticks,\n horiz = axis.horiz,\n side = axis.side,\n invertedSide = chart.inverted && !axis.isZAxis ? [1, 0, 3, 2][side] : side,\n hasData,\n showAxis,\n titleOffset = 0,\n titleOffsetOption,\n titleMargin = 0,\n axisTitleOptions = options.title,\n labelOptions = options.labels,\n labelOffset = 0, // reset\n labelOffsetPadded,\n axisOffset = chart.axisOffset,\n clipOffset = chart.clipOffset,\n clip,\n directionFactor = [-1, 1, 1, -1][side],\n className = options.className,\n axisParent = axis.axisParent, // Used in color axis\n lineHeightCorrection,\n tickSize = this.tickSize('tick');\n\n // For reuse in Axis.render\n hasData = axis.hasData();\n axis.showAxis = showAxis = hasData || pick(options.showEmpty, true);\n\n // Set/reset staggerLines\n axis.staggerLines = axis.horiz && labelOptions.staggerLines;\n\n // Create the axisGroup and gridGroup elements on first iteration\n if (!axis.axisGroup) {\n axis.gridGroup = renderer.g('grid')\n .attr({\n zIndex: options.gridZIndex || 1\n })\n .addClass('highcharts-' + this.coll.toLowerCase() + '-grid ' + (className || ''))\n .add(axisParent);\n axis.axisGroup = renderer.g('axis')\n .attr({\n zIndex: options.zIndex || 2\n })\n .addClass('highcharts-' + this.coll.toLowerCase() + ' ' + (className || ''))\n .add(axisParent);\n axis.labelGroup = renderer.g('axis-labels')\n .attr({\n zIndex: labelOptions.zIndex || 7\n })\n .addClass('highcharts-' + axis.coll.toLowerCase() + '-labels ' + (className || ''))\n .add(axisParent);\n }\n\n if (hasData || axis.isLinked) {\n\n // Generate ticks\n each(tickPositions, function(pos, i) {\n // i is not used here, but may be used in overrides\n axis.generateTick(pos, i);\n });\n\n axis.renderUnsquish();\n\n\n // Left side must be align: right and right side must have align: left for labels\n if (labelOptions.reserveSpace !== false && (side === 0 || side === 2 || {\n 1: 'left',\n 3: 'right'\n }[side] === axis.labelAlign || axis.labelAlign === 'center')) {\n each(tickPositions, function(pos) {\n\n // get the highest offset\n labelOffset = Math.max(\n ticks[pos].getLabelSize(),\n labelOffset\n );\n });\n }\n\n if (axis.staggerLines) {\n labelOffset *= axis.staggerLines;\n axis.labelOffset = labelOffset * (axis.opposite ? -1 : 1);\n }\n\n\n } else { // doesn't have data\n objectEach(ticks, function(tick, n) {\n tick.destroy();\n delete ticks[n];\n });\n }\n\n if (axisTitleOptions && axisTitleOptions.text && axisTitleOptions.enabled !== false) {\n axis.addTitle(showAxis);\n\n if (showAxis && axisTitleOptions.reserveSpace !== false) {\n axis.titleOffset = titleOffset =\n axis.axisTitle.getBBox()[horiz ? 'height' : 'width'];\n titleOffsetOption = axisTitleOptions.offset;\n titleMargin = defined(titleOffsetOption) ? 0 : pick(axisTitleOptions.margin, horiz ? 5 : 10);\n }\n }\n\n // Render the axis line\n axis.renderLine();\n\n // handle automatic or user set offset\n axis.offset = directionFactor * pick(options.offset, axisOffset[side]);\n\n axis.tickRotCorr = axis.tickRotCorr || {\n x: 0,\n y: 0\n }; // polar\n if (side === 0) {\n lineHeightCorrection = -axis.labelMetrics().h;\n } else if (side === 2) {\n lineHeightCorrection = axis.tickRotCorr.y;\n } else {\n lineHeightCorrection = 0;\n }\n\n // Find the padded label offset\n labelOffsetPadded = Math.abs(labelOffset) + titleMargin;\n if (labelOffset) {\n labelOffsetPadded -= lineHeightCorrection;\n labelOffsetPadded += directionFactor * (horiz ? pick(labelOptions.y, axis.tickRotCorr.y + directionFactor * 8) : labelOptions.x);\n }\n axis.axisTitleMargin = pick(titleOffsetOption, labelOffsetPadded);\n\n axisOffset[side] = Math.max(\n axisOffset[side],\n axis.axisTitleMargin + titleOffset + directionFactor * axis.offset,\n labelOffsetPadded, // #3027\n hasData && tickPositions.length && tickSize ?\n tickSize[0] + directionFactor * axis.offset :\n 0 // #4866\n );\n\n // Decide the clipping needed to keep the graph inside the plot area and\n // axis lines\n clip = Math.floor(axis.axisLine.strokeWidth() / 2) * 2; // #4308, #4371\n if (options.offset > 0) {\n clip -= options.offset * 2;\n }\n clipOffset[invertedSide] = Math.max(\n clipOffset[invertedSide] || clip,\n clip\n );\n },\n\n /**\n * Internal function to get the path for the axis line. Extended for polar\n * charts.\n *\n * @param {Number} lineWidth\n * The line width in pixels.\n * @return {Array}\n * The SVG path definition in array form.\n */\n getLinePath: function(lineWidth) {\n var chart = this.chart,\n opposite = this.opposite,\n offset = this.offset,\n horiz = this.horiz,\n lineLeft = this.left + (opposite ? this.width : 0) + offset,\n lineTop = chart.chartHeight - this.bottom -\n (opposite ? this.height : 0) + offset;\n\n if (opposite) {\n lineWidth *= -1; // crispify the other way - #1480, #1687\n }\n\n return chart.renderer\n .crispLine([\n 'M',\n horiz ?\n this.left :\n lineLeft,\n horiz ?\n lineTop :\n this.top,\n 'L',\n horiz ?\n chart.chartWidth - this.right :\n lineLeft,\n horiz ?\n lineTop :\n chart.chartHeight - this.bottom\n ], lineWidth);\n },\n\n /**\n * Render the axis line\n */\n renderLine: function() {\n if (!this.axisLine) {\n this.axisLine = this.chart.renderer.path()\n .addClass('highcharts-axis-line')\n .add(this.axisGroup);\n\n\n this.axisLine.attr({\n stroke: this.options.lineColor,\n 'stroke-width': this.options.lineWidth,\n zIndex: 7\n });\n\n }\n },\n\n /**\n * Position the title\n */\n getTitlePosition: function() {\n // compute anchor points for each of the title align options\n var horiz = this.horiz,\n axisLeft = this.left,\n axisTop = this.top,\n axisLength = this.len,\n axisTitleOptions = this.options.title,\n margin = horiz ? axisLeft : axisTop,\n opposite = this.opposite,\n offset = this.offset,\n xOption = axisTitleOptions.x || 0,\n yOption = axisTitleOptions.y || 0,\n fontSize = this.chart.renderer.fontMetrics(axisTitleOptions.style && axisTitleOptions.style.fontSize, this.axisTitle).f,\n\n // the position in the length direction of the axis\n alongAxis = {\n low: margin + (horiz ? 0 : axisLength),\n middle: margin + axisLength / 2,\n high: margin + (horiz ? axisLength : 0)\n }[axisTitleOptions.align],\n\n // the position in the perpendicular direction of the axis\n offAxis = (horiz ? axisTop + this.height : axisLeft) +\n (horiz ? 1 : -1) * // horizontal axis reverses the margin\n (opposite ? -1 : 1) * // so does opposite axes\n this.axisTitleMargin +\n (this.side === 2 ? fontSize : 0);\n\n return {\n x: horiz ?\n alongAxis + xOption : offAxis + (opposite ? this.width : 0) + offset + xOption,\n y: horiz ?\n offAxis + yOption - (opposite ? this.height : 0) + offset : alongAxis + yOption\n };\n },\n\n /**\n * Render a minor tick into the given position. If a minor tick already \n * exists in this position, move it.\n * @param {number} pos - The position in axis values.\n */\n renderMinorTick: function(pos) {\n var slideInTicks = this.chart.hasRendered && isNumber(this.oldMin),\n minorTicks = this.minorTicks;\n\n if (!minorTicks[pos]) {\n minorTicks[pos] = new Tick(this, pos, 'minor');\n }\n\n // Render new ticks in old position\n if (slideInTicks && minorTicks[pos].isNew) {\n minorTicks[pos].render(null, true);\n }\n\n minorTicks[pos].render(null, false, 1);\n },\n\n /**\n * Render a major tick into the given position. If a tick already exists\n * in this position, move it.\n * @param {number} pos - The position in axis values\n * @param {number} i - The tick index\n */\n renderTick: function(pos, i) {\n var isLinked = this.isLinked,\n ticks = this.ticks,\n slideInTicks = this.chart.hasRendered && isNumber(this.oldMin);\n\n // Linked axes need an extra check to find out if\n if (!isLinked || (pos >= this.min && pos <= this.max)) {\n\n if (!ticks[pos]) {\n ticks[pos] = new Tick(this, pos);\n }\n\n // render new ticks in old position\n if (slideInTicks && ticks[pos].isNew) {\n ticks[pos].render(i, true, 0.1);\n }\n\n ticks[pos].render(i);\n }\n },\n\n /**\n * Render the axis\n */\n render: function() {\n var axis = this,\n chart = axis.chart,\n renderer = chart.renderer,\n options = axis.options,\n isLog = axis.isLog,\n lin2log = axis.lin2log,\n isLinked = axis.isLinked,\n tickPositions = axis.tickPositions,\n axisTitle = axis.axisTitle,\n ticks = axis.ticks,\n minorTicks = axis.minorTicks,\n alternateBands = axis.alternateBands,\n stackLabelOptions = options.stackLabels,\n alternateGridColor = options.alternateGridColor,\n tickmarkOffset = axis.tickmarkOffset,\n axisLine = axis.axisLine,\n showAxis = axis.showAxis,\n animation = animObject(renderer.globalAnimation),\n from,\n to;\n\n // Reset\n axis.labelEdge.length = 0;\n //axis.justifyToPlot = overflow === 'justify';\n axis.overlap = false;\n\n // Mark all elements inActive before we go over and mark the active ones\n each([ticks, minorTicks, alternateBands], function(coll) {\n objectEach(coll, function(tick) {\n tick.isActive = false;\n });\n });\n\n // If the series has data draw the ticks. Else only the line and title\n if (axis.hasData() || isLinked) {\n\n // minor ticks\n if (axis.minorTickInterval && !axis.categories) {\n each(axis.getMinorTickPositions(), function(pos) {\n axis.renderMinorTick(pos);\n });\n }\n\n // Major ticks. Pull out the first item and render it last so that\n // we can get the position of the neighbour label. #808.\n if (tickPositions.length) { // #1300\n each(tickPositions, function(pos, i) {\n axis.renderTick(pos, i);\n });\n // In a categorized axis, the tick marks are displayed between labels. So\n // we need to add a tick mark and grid line at the left edge of the X axis.\n if (tickmarkOffset && (axis.min === 0 || axis.single)) {\n if (!ticks[-1]) {\n ticks[-1] = new Tick(axis, -1, null, true);\n }\n ticks[-1].render(-1);\n }\n\n }\n\n // alternate grid color\n if (alternateGridColor) {\n each(tickPositions, function(pos, i) {\n to = tickPositions[i + 1] !== undefined ? tickPositions[i + 1] + tickmarkOffset : axis.max - tickmarkOffset;\n if (i % 2 === 0 && pos < axis.max && to <= axis.max + (chart.polar ? -tickmarkOffset : tickmarkOffset)) { // #2248, #4660\n if (!alternateBands[pos]) {\n alternateBands[pos] = new H.PlotLineOrBand(axis);\n }\n from = pos + tickmarkOffset; // #949\n alternateBands[pos].options = {\n from: isLog ? lin2log(from) : from,\n to: isLog ? lin2log(to) : to,\n color: alternateGridColor\n };\n alternateBands[pos].render();\n alternateBands[pos].isActive = true;\n }\n });\n }\n\n // custom plot lines and bands\n if (!axis._addedPlotLB) { // only first time\n each((options.plotLines || []).concat(options.plotBands || []), function(plotLineOptions) {\n axis.addPlotBandOrLine(plotLineOptions);\n });\n axis._addedPlotLB = true;\n }\n\n } // end if hasData\n\n // Remove inactive ticks\n each([ticks, minorTicks, alternateBands], function(coll) {\n var i,\n forDestruction = [],\n delay = animation.duration,\n destroyInactiveItems = function() {\n i = forDestruction.length;\n while (i--) {\n // When resizing rapidly, the same items may be destroyed in different timeouts,\n // or the may be reactivated\n if (coll[forDestruction[i]] && !coll[forDestruction[i]].isActive) {\n coll[forDestruction[i]].destroy();\n delete coll[forDestruction[i]];\n }\n }\n\n };\n\n objectEach(coll, function(tick, pos) {\n if (!tick.isActive) {\n // Render to zero opacity\n tick.render(pos, false, 0);\n tick.isActive = false;\n forDestruction.push(pos);\n }\n });\n\n // When the objects are finished fading out, destroy them\n syncTimeout(\n destroyInactiveItems,\n coll === alternateBands || !chart.hasRendered || !delay ? 0 : delay\n );\n });\n\n // Set the axis line path\n if (axisLine) {\n axisLine[axisLine.isPlaced ? 'animate' : 'attr']({\n d: this.getLinePath(axisLine.strokeWidth())\n });\n axisLine.isPlaced = true;\n\n // Show or hide the line depending on options.showEmpty\n axisLine[showAxis ? 'show' : 'hide'](true);\n }\n\n if (axisTitle && showAxis) {\n var titleXy = axis.getTitlePosition();\n if (isNumber(titleXy.y)) {\n axisTitle[axisTitle.isNew ? 'attr' : 'animate'](titleXy);\n axisTitle.isNew = false;\n } else {\n axisTitle.attr('y', -9999);\n axisTitle.isNew = true;\n }\n }\n\n // Stacked totals:\n if (stackLabelOptions && stackLabelOptions.enabled) {\n axis.renderStackTotals();\n }\n // End stacked totals\n\n axis.isDirty = false;\n },\n\n /**\n * Redraw the axis to reflect changes in the data or axis extremes\n */\n redraw: function() {\n\n if (this.visible) {\n // render the axis\n this.render();\n\n // move plot lines and bands\n each(this.plotLinesAndBands, function(plotLine) {\n plotLine.render();\n });\n }\n\n // mark associated series as dirty and ready for redraw\n each(this.series, function(series) {\n series.isDirty = true;\n });\n\n },\n\n // Properties to survive after destroy, needed for Axis.update (#4317,\n // #5773, #5881).\n keepProps: ['extKey', 'hcEvents', 'names', 'series', 'userMax', 'userMin'],\n\n /**\n * Destroys an Axis instance. See {@link Axis#remove} for the API endpoint\n * to fully remove the axis.\n *\n * @private\n * @param {Boolean} keepEvents\n * Whether to preserve events, used internally in Axis.update.\n */\n destroy: function(keepEvents) {\n var axis = this,\n stacks = axis.stacks,\n plotLinesAndBands = axis.plotLinesAndBands,\n plotGroup,\n i;\n\n // Remove the events\n if (!keepEvents) {\n removeEvent(axis);\n }\n\n // Destroy each stack total\n objectEach(stacks, function(stack, stackKey) {\n destroyObjectProperties(stack);\n\n stacks[stackKey] = null;\n });\n\n // Destroy collections\n each([axis.ticks, axis.minorTicks, axis.alternateBands], function(coll) {\n destroyObjectProperties(coll);\n });\n if (plotLinesAndBands) {\n i = plotLinesAndBands.length;\n while (i--) { // #1975\n plotLinesAndBands[i].destroy();\n }\n }\n\n // Destroy local variables\n each(['stackTotalGroup', 'axisLine', 'axisTitle', 'axisGroup', 'gridGroup', 'labelGroup', 'cross'], function(prop) {\n if (axis[prop]) {\n axis[prop] = axis[prop].destroy();\n }\n });\n\n // Destroy each generated group for plotlines and plotbands\n for (plotGroup in axis.plotLinesAndBandsGroups) {\n axis.plotLinesAndBandsGroups[plotGroup] = axis.plotLinesAndBandsGroups[plotGroup].destroy();\n }\n\n // Delete all properties and fall back to the prototype.\n objectEach(axis, function(val, key) {\n if (inArray(key, axis.keepProps) === -1) {\n delete axis[key];\n }\n });\n },\n\n /**\n * Internal function to draw a crosshair.\n *\n * @param {PointerEvent} [e]\n * The event arguments from the modified pointer event, extended \n * with `chartX` and `chartY`\n * @param {Point} [point]\n * The Point object if the crosshair snaps to points.\n */\n drawCrosshair: function(e, point) {\n\n var path,\n options = this.crosshair,\n snap = pick(options.snap, true),\n pos,\n categorized,\n graphic = this.cross;\n\n // Use last available event when updating non-snapped crosshairs without\n // mouse interaction (#5287)\n if (!e) {\n e = this.cross && this.cross.e;\n }\n\n if (\n // Disabled in options\n !this.crosshair ||\n // Snap\n ((defined(point) || !snap) === false)\n ) {\n this.hideCrosshair();\n } else {\n\n // Get the path\n if (!snap) {\n pos = e && (this.horiz ? e.chartX - this.pos : this.len - e.chartY + this.pos);\n } else if (defined(point)) {\n pos = this.isXAxis ? point.plotX : this.len - point.plotY; // #3834\n }\n\n if (defined(pos)) {\n path = this.getPlotLinePath(\n // First argument, value, only used on radial\n point && (this.isXAxis ? point.x : pick(point.stackY, point.y)),\n null,\n null,\n null,\n pos // Translated position\n ) || null; // #3189\n }\n\n if (!defined(path)) {\n this.hideCrosshair();\n return;\n }\n\n categorized = this.categories && !this.isRadial;\n\n // Draw the cross\n if (!graphic) {\n this.cross = graphic = this.chart.renderer\n .path()\n .addClass('highcharts-crosshair highcharts-crosshair-' +\n (categorized ? 'category ' : 'thin ') + options.className)\n .attr({\n zIndex: pick(options.zIndex, 2)\n })\n .add();\n\n\n // Presentational attributes\n graphic.attr({\n 'stroke': options.color || (categorized ? color('#ccd6eb').setOpacity(0.25).get() : '#cccccc'),\n 'stroke-width': pick(options.width, 1)\n });\n if (options.dashStyle) {\n graphic.attr({\n dashstyle: options.dashStyle\n });\n }\n\n\n }\n\n graphic.show().attr({\n d: path\n });\n\n if (categorized && !options.width) {\n graphic.attr({\n 'stroke-width': this.transA\n });\n }\n this.cross.e = e;\n }\n },\n\n /**\n * Hide the crosshair.\n */\n hideCrosshair: function() {\n if (this.cross) {\n this.cross.hide();\n }\n }\n }); // end Axis\n\n H.Axis = Axis;\n return Axis;\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var Axis = H.Axis,\n Date = H.Date,\n dateFormat = H.dateFormat,\n defaultOptions = H.defaultOptions,\n defined = H.defined,\n each = H.each,\n extend = H.extend,\n getMagnitude = H.getMagnitude,\n getTZOffset = H.getTZOffset,\n normalizeTickInterval = H.normalizeTickInterval,\n pick = H.pick,\n timeUnits = H.timeUnits;\n /**\n * Set the tick positions to a time unit that makes sense, for example\n * on the first of each month or on every Monday. Return an array\n * with the time positions. Used in datetime axes as well as for grouping\n * data on a datetime axis.\n *\n * @param {Object} normalizedInterval The interval in axis values (ms) and the count\n * @param {Number} min The minimum in axis values\n * @param {Number} max The maximum in axis values\n * @param {Number} startOfWeek\n */\n Axis.prototype.getTimeTicks = function(normalizedInterval, min, max, startOfWeek) {\n var tickPositions = [],\n i,\n higherRanks = {},\n useUTC = defaultOptions.global.useUTC,\n minYear, // used in months and years as a basis for Date.UTC()\n // When crossing DST, use the max. Resolves #6278.\n minDate = new Date(min - Math.max(getTZOffset(min), getTZOffset(max))),\n makeTime = Date.hcMakeTime,\n interval = normalizedInterval.unitRange,\n count = normalizedInterval.count,\n variableDayLength;\n\n if (defined(min)) { // #1300\n minDate[Date.hcSetMilliseconds](interval >= timeUnits.second ? 0 : // #3935\n count * Math.floor(minDate.getMilliseconds() / count)); // #3652, #3654\n\n if (interval >= timeUnits.second) { // second\n minDate[Date.hcSetSeconds](interval >= timeUnits.minute ? 0 : // #3935\n count * Math.floor(minDate.getSeconds() / count));\n }\n\n if (interval >= timeUnits.minute) { // minute\n minDate[Date.hcSetMinutes](interval >= timeUnits.hour ? 0 :\n count * Math.floor(minDate[Date.hcGetMinutes]() / count));\n }\n\n if (interval >= timeUnits.hour) { // hour\n minDate[Date.hcSetHours](interval >= timeUnits.day ? 0 :\n count * Math.floor(minDate[Date.hcGetHours]() / count));\n }\n\n if (interval >= timeUnits.day) { // day\n minDate[Date.hcSetDate](interval >= timeUnits.month ? 1 :\n count * Math.floor(minDate[Date.hcGetDate]() / count));\n }\n\n if (interval >= timeUnits.month) { // month\n minDate[Date.hcSetMonth](interval >= timeUnits.year ? 0 :\n count * Math.floor(minDate[Date.hcGetMonth]() / count));\n minYear = minDate[Date.hcGetFullYear]();\n }\n\n if (interval >= timeUnits.year) { // year\n minYear -= minYear % count;\n minDate[Date.hcSetFullYear](minYear);\n }\n\n // week is a special case that runs outside the hierarchy\n if (interval === timeUnits.week) {\n // get start of current week, independent of count\n minDate[Date.hcSetDate](minDate[Date.hcGetDate]() - minDate[Date.hcGetDay]() +\n pick(startOfWeek, 1));\n }\n\n\n // Get basics for variable time spans\n minYear = minDate[Date.hcGetFullYear]();\n var minMonth = minDate[Date.hcGetMonth](),\n minDateDate = minDate[Date.hcGetDate](),\n minHours = minDate[Date.hcGetHours]();\n\n\n // Handle local timezone offset\n if (Date.hcTimezoneOffset || Date.hcGetTimezoneOffset) {\n\n // Detect whether we need to take the DST crossover into\n // consideration. If we're crossing over DST, the day length may be\n // 23h or 25h and we need to compute the exact clock time for each\n // tick instead of just adding hours. This comes at a cost, so first\n // we found out if it is needed. #4951.\n variableDayLength =\n (!useUTC || !!Date.hcGetTimezoneOffset) &&\n (\n // Long range, assume we're crossing over.\n max - min > 4 * timeUnits.month ||\n // Short range, check if min and max are in different time \n // zones.\n getTZOffset(min) !== getTZOffset(max)\n );\n\n // Adjust minDate to the offset date\n minDate = minDate.getTime();\n minDate = new Date(minDate + getTZOffset(minDate));\n }\n\n\n // Iterate and add tick positions at appropriate values\n var time = minDate.getTime();\n i = 1;\n while (time < max) {\n tickPositions.push(time);\n\n // if the interval is years, use Date.UTC to increase years\n if (interval === timeUnits.year) {\n time = makeTime(minYear + i * count, 0);\n\n // if the interval is months, use Date.UTC to increase months\n } else if (interval === timeUnits.month) {\n time = makeTime(minYear, minMonth + i * count);\n\n // if we're using global time, the interval is not fixed as it jumps\n // one hour at the DST crossover\n } else if (variableDayLength && (interval === timeUnits.day || interval === timeUnits.week)) {\n time = makeTime(minYear, minMonth, minDateDate +\n i * count * (interval === timeUnits.day ? 1 : 7));\n\n } else if (variableDayLength && interval === timeUnits.hour) {\n time = makeTime(minYear, minMonth, minDateDate, minHours + i * count);\n\n // else, the interval is fixed and we use simple addition\n } else {\n time += interval * count;\n }\n\n i++;\n }\n\n // push the last time\n tickPositions.push(time);\n\n\n // Handle higher ranks. Mark new days if the time is on midnight\n // (#950, #1649, #1760, #3349). Use a reasonable dropout threshold to \n // prevent looping over dense data grouping (#6156).\n if (interval <= timeUnits.hour && tickPositions.length < 10000) {\n each(tickPositions, function(time) {\n if (\n // Speed optimization, no need to run dateFormat unless\n // we're on a full or half hour\n time % 1800000 === 0 &&\n // Check for local or global midnight\n dateFormat('%H%M%S%L', time) === '000000000'\n ) {\n higherRanks[time] = 'day';\n }\n });\n }\n }\n\n\n // record information on the chosen unit - for dynamic label formatter\n tickPositions.info = extend(normalizedInterval, {\n higherRanks: higherRanks,\n totalRange: interval * count\n });\n\n return tickPositions;\n };\n\n /**\n * Get a normalized tick interval for dates. Returns a configuration object with\n * unit range (interval), count and name. Used to prepare data for getTimeTicks.\n * Previously this logic was part of getTimeTicks, but as getTimeTicks now runs\n * of segments in stock charts, the normalizing logic was extracted in order to\n * prevent it for running over again for each segment having the same interval.\n * #662, #697.\n */\n Axis.prototype.normalizeTimeTickInterval = function(tickInterval, unitsOption) {\n var units = unitsOption || [\n [\n 'millisecond', // unit name\n [1, 2, 5, 10, 20, 25, 50, 100, 200, 500] // allowed multiples\n ],\n [\n 'second', [1, 2, 5, 10, 15, 30]\n ],\n [\n 'minute', [1, 2, 5, 10, 15, 30]\n ],\n [\n 'hour', [1, 2, 3, 4, 6, 8, 12]\n ],\n [\n 'day', [1, 2]\n ],\n [\n 'week', [1, 2]\n ],\n [\n 'month', [1, 2, 3, 4, 6]\n ],\n [\n 'year',\n null\n ]\n ],\n unit = units[units.length - 1], // default unit is years\n interval = timeUnits[unit[0]],\n multiples = unit[1],\n count,\n i;\n\n // loop through the units to find the one that best fits the tickInterval\n for (i = 0; i < units.length; i++) {\n unit = units[i];\n interval = timeUnits[unit[0]];\n multiples = unit[1];\n\n\n if (units[i + 1]) {\n // lessThan is in the middle between the highest multiple and the next unit.\n var lessThan = (interval * multiples[multiples.length - 1] +\n timeUnits[units[i + 1][0]]) / 2;\n\n // break and keep the current unit\n if (tickInterval <= lessThan) {\n break;\n }\n }\n }\n\n // prevent 2.5 years intervals, though 25, 250 etc. are allowed\n if (interval === timeUnits.year && tickInterval < 5 * interval) {\n multiples = [1, 2, 5];\n }\n\n // get the count\n count = normalizeTickInterval(\n tickInterval / interval,\n multiples,\n unit[0] === 'year' ? Math.max(getMagnitude(tickInterval / interval), 1) : 1 // #1913, #2360\n );\n\n return {\n unitRange: interval,\n count: count,\n unitName: unit[0]\n };\n };\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var Axis = H.Axis,\n getMagnitude = H.getMagnitude,\n map = H.map,\n normalizeTickInterval = H.normalizeTickInterval,\n pick = H.pick;\n /**\n * Methods defined on the Axis prototype\n */\n\n /**\n * Set the tick positions of a logarithmic axis\n */\n Axis.prototype.getLogTickPositions = function(interval, min, max, minor) {\n var axis = this,\n options = axis.options,\n axisLength = axis.len,\n lin2log = axis.lin2log,\n log2lin = axis.log2lin,\n // Since we use this method for both major and minor ticks,\n // use a local variable and return the result\n positions = [];\n\n // Reset\n if (!minor) {\n axis._minorAutoInterval = null;\n }\n\n // First case: All ticks fall on whole logarithms: 1, 10, 100 etc.\n if (interval >= 0.5) {\n interval = Math.round(interval);\n positions = axis.getLinearTickPositions(interval, min, max);\n\n // Second case: We need intermediary ticks. For example\n // 1, 2, 4, 6, 8, 10, 20, 40 etc.\n } else if (interval >= 0.08) {\n var roundedMin = Math.floor(min),\n intermediate,\n i,\n j,\n len,\n pos,\n lastPos,\n break2;\n\n if (interval > 0.3) {\n intermediate = [1, 2, 4];\n } else if (interval > 0.15) { // 0.2 equals five minor ticks per 1, 10, 100 etc\n intermediate = [1, 2, 4, 6, 8];\n } else { // 0.1 equals ten minor ticks per 1, 10, 100 etc\n intermediate = [1, 2, 3, 4, 5, 6, 7, 8, 9];\n }\n\n for (i = roundedMin; i < max + 1 && !break2; i++) {\n len = intermediate.length;\n for (j = 0; j < len && !break2; j++) {\n pos = log2lin(lin2log(i) * intermediate[j]);\n if (pos > min && (!minor || lastPos <= max) && lastPos !== undefined) { // #1670, lastPos is #3113\n positions.push(lastPos);\n }\n\n if (lastPos > max) {\n break2 = true;\n }\n lastPos = pos;\n }\n }\n\n // Third case: We are so deep in between whole logarithmic values that\n // we might as well handle the tick positions like a linear axis. For\n // example 1.01, 1.02, 1.03, 1.04.\n } else {\n var realMin = lin2log(min),\n realMax = lin2log(max),\n tickIntervalOption = options[minor ? 'minorTickInterval' : 'tickInterval'],\n filteredTickIntervalOption = tickIntervalOption === 'auto' ? null : tickIntervalOption,\n tickPixelIntervalOption = options.tickPixelInterval / (minor ? 5 : 1),\n totalPixelLength = minor ? axisLength / axis.tickPositions.length : axisLength;\n\n interval = pick(\n filteredTickIntervalOption,\n axis._minorAutoInterval,\n (realMax - realMin) * tickPixelIntervalOption / (totalPixelLength || 1)\n );\n\n interval = normalizeTickInterval(\n interval,\n null,\n getMagnitude(interval)\n );\n\n positions = map(axis.getLinearTickPositions(\n interval,\n realMin,\n realMax\n ), log2lin);\n\n if (!minor) {\n axis._minorAutoInterval = interval / 5;\n }\n }\n\n // Set the axis-level tickInterval variable\n if (!minor) {\n axis.tickInterval = interval;\n }\n return positions;\n };\n\n Axis.prototype.log2lin = function(num) {\n return Math.log(num) / Math.LN10;\n };\n\n Axis.prototype.lin2log = function(num) {\n return Math.pow(10, num);\n };\n\n }(Highcharts));\n (function(H, Axis) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var arrayMax = H.arrayMax,\n arrayMin = H.arrayMin,\n defined = H.defined,\n destroyObjectProperties = H.destroyObjectProperties,\n each = H.each,\n erase = H.erase,\n merge = H.merge,\n pick = H.pick;\n /*\n * The object wrapper for plot lines and plot bands\n * @param {Object} options\n */\n H.PlotLineOrBand = function(axis, options) {\n this.axis = axis;\n\n if (options) {\n this.options = options;\n this.id = options.id;\n }\n };\n\n H.PlotLineOrBand.prototype = {\n\n /**\n * Render the plot line or plot band. If it is already existing,\n * move it.\n */\n render: function() {\n var plotLine = this,\n axis = plotLine.axis,\n horiz = axis.horiz,\n options = plotLine.options,\n optionsLabel = options.label,\n label = plotLine.label,\n to = options.to,\n from = options.from,\n value = options.value,\n isBand = defined(from) && defined(to),\n isLine = defined(value),\n svgElem = plotLine.svgElem,\n isNew = !svgElem,\n path = [],\n color = options.color,\n zIndex = pick(options.zIndex, 0),\n events = options.events,\n attribs = {\n 'class': 'highcharts-plot-' + (isBand ? 'band ' : 'line ') + (options.className || '')\n },\n groupAttribs = {},\n renderer = axis.chart.renderer,\n groupName = isBand ? 'bands' : 'lines',\n group,\n log2lin = axis.log2lin;\n\n // logarithmic conversion\n if (axis.isLog) {\n from = log2lin(from);\n to = log2lin(to);\n value = log2lin(value);\n }\n\n\n // Set the presentational attributes\n if (isLine) {\n attribs = {\n stroke: color,\n 'stroke-width': options.width\n };\n if (options.dashStyle) {\n attribs.dashstyle = options.dashStyle;\n }\n\n } else if (isBand) { // plot band\n if (color) {\n attribs.fill = color;\n }\n if (options.borderWidth) {\n attribs.stroke = options.borderColor;\n attribs['stroke-width'] = options.borderWidth;\n }\n }\n\n\n // Grouping and zIndex\n groupAttribs.zIndex = zIndex;\n groupName += '-' + zIndex;\n\n group = axis.plotLinesAndBandsGroups[groupName];\n if (!group) {\n axis.plotLinesAndBandsGroups[groupName] = group = renderer.g('plot-' + groupName)\n .attr(groupAttribs).add();\n }\n\n // Create the path\n if (isNew) {\n plotLine.svgElem = svgElem =\n renderer\n .path()\n .attr(attribs).add(group);\n }\n\n\n // Set the path or return\n if (isLine) {\n path = axis.getPlotLinePath(value, svgElem.strokeWidth());\n } else if (isBand) { // plot band\n path = axis.getPlotBandPath(from, to, options);\n } else {\n return;\n }\n\n\n // common for lines and bands\n if (isNew && path && path.length) {\n svgElem.attr({\n d: path\n });\n\n // events\n if (events) {\n H.objectEach(events, function(event, eventType) {\n svgElem.on(eventType, function(e) {\n events[eventType].apply(plotLine, [e]);\n });\n });\n }\n } else if (svgElem) {\n if (path) {\n svgElem.show();\n svgElem.animate({\n d: path\n });\n } else {\n svgElem.hide();\n if (label) {\n plotLine.label = label = label.destroy();\n }\n }\n }\n\n // the plot band/line label\n if (optionsLabel && defined(optionsLabel.text) && path && path.length &&\n axis.width > 0 && axis.height > 0 && !path.flat) {\n // apply defaults\n optionsLabel = merge({\n align: horiz && isBand && 'center',\n x: horiz ? !isBand && 4 : 10,\n verticalAlign: !horiz && isBand && 'middle',\n y: horiz ? isBand ? 16 : 10 : isBand ? 6 : -4,\n rotation: horiz && !isBand && 90\n }, optionsLabel);\n\n this.renderLabel(optionsLabel, path, isBand, zIndex);\n\n } else if (label) { // move out of sight\n label.hide();\n }\n\n // chainable\n return plotLine;\n },\n\n /**\n * Render and align label for plot line or band.\n */\n renderLabel: function(optionsLabel, path, isBand, zIndex) {\n var plotLine = this,\n label = plotLine.label,\n renderer = plotLine.axis.chart.renderer,\n attribs,\n xs,\n ys,\n x,\n y;\n\n // add the SVG element\n if (!label) {\n attribs = {\n align: optionsLabel.textAlign || optionsLabel.align,\n rotation: optionsLabel.rotation,\n 'class': 'highcharts-plot-' + (isBand ? 'band' : 'line') + '-label ' + (optionsLabel.className || '')\n };\n\n attribs.zIndex = zIndex;\n\n plotLine.label = label = renderer.text(\n optionsLabel.text,\n 0,\n 0,\n optionsLabel.useHTML\n )\n .attr(attribs)\n .add();\n\n\n label.css(optionsLabel.style);\n\n }\n\n // get the bounding box and align the label\n // #3000 changed to better handle choice between plotband or plotline\n xs = [path[1], path[4], (isBand ? path[6] : path[1])];\n ys = [path[2], path[5], (isBand ? path[7] : path[2])];\n x = arrayMin(xs);\n y = arrayMin(ys);\n\n label.align(optionsLabel, false, {\n x: x,\n y: y,\n width: arrayMax(xs) - x,\n height: arrayMax(ys) - y\n });\n label.show();\n },\n\n /**\n * Remove the plot line or band\n */\n destroy: function() {\n // remove it from the lookup\n erase(this.axis.plotLinesAndBands, this);\n\n delete this.axis;\n destroyObjectProperties(this);\n }\n };\n\n /**\n * Object with members for extending the Axis prototype\n * @todo Extend directly instead of adding object to Highcharts first\n */\n\n H.extend(Axis.prototype, /** @lends Highcharts.Axis.prototype */ {\n\n /**\n * Create the path for a plot band\n */\n getPlotBandPath: function(from, to) {\n var toPath = this.getPlotLinePath(to, null, null, true),\n path = this.getPlotLinePath(from, null, null, true),\n // #4964 check if chart is inverted or plotband is on yAxis \n horiz = this.horiz,\n plus = 1,\n outside =\n (from < this.min && to < this.min) ||\n (from > this.max && to > this.max);\n\n if (path && toPath) {\n\n // Flat paths don't need labels (#3836)\n if (outside) {\n path.flat = path.toString() === toPath.toString();\n plus = 0;\n }\n\n // Add 1 pixel, when coordinates are the same\n path.push(\n horiz && toPath[4] === path[4] ? toPath[4] + plus : toPath[4], !horiz && toPath[5] === path[5] ? toPath[5] + plus : toPath[5],\n horiz && toPath[1] === path[1] ? toPath[1] + plus : toPath[1], !horiz && toPath[2] === path[2] ? toPath[2] + plus : toPath[2]\n );\n } else { // outside the axis area\n path = null;\n }\n\n return path;\n },\n\n /**\n * Add a plot band after render time.\n *\n * @param {AxisPlotBandsOptions} options\n * A configuration object for the plot band, as defined in {@link\n * https://api.highcharts.com/highcharts/xAxis.plotBands|\n * xAxis.plotBands}.\n * @return {Object}\n * The added plot band.\n * @sample highcharts/members/axis-addplotband/\n * Toggle the plot band from a button\n */\n addPlotBand: function(options) {\n return this.addPlotBandOrLine(options, 'plotBands');\n },\n\n /**\n * Add a plot line after render time.\n * \n * @param {AxisPlotLinesOptions} options\n * A configuration object for the plot line, as defined in {@link\n * https://api.highcharts.com/highcharts/xAxis.plotLines|\n * xAxis.plotLines}.\n * @return {Object}\n * The added plot line.\n * @sample highcharts/members/axis-addplotline/\n * Toggle the plot line from a button\n */\n addPlotLine: function(options) {\n return this.addPlotBandOrLine(options, 'plotLines');\n },\n\n /**\n * Add a plot band or plot line after render time. Called from addPlotBand\n * and addPlotLine internally.\n *\n * @private\n * @param options {AxisPlotLinesOptions|AxisPlotBandsOptions}\n * The plotBand or plotLine configuration object.\n */\n addPlotBandOrLine: function(options, coll) {\n var obj = new H.PlotLineOrBand(this, options).render(),\n userOptions = this.userOptions;\n\n if (obj) { // #2189\n // Add it to the user options for exporting and Axis.update\n if (coll) {\n userOptions[coll] = userOptions[coll] || [];\n userOptions[coll].push(options);\n }\n this.plotLinesAndBands.push(obj);\n }\n\n return obj;\n },\n\n /**\n * Remove a plot band or plot line from the chart by id. Called internally\n * from `removePlotBand` and `removePlotLine`.\n *\n * @private\n * @param {String} id\n */\n removePlotBandOrLine: function(id) {\n var plotLinesAndBands = this.plotLinesAndBands,\n options = this.options,\n userOptions = this.userOptions,\n i = plotLinesAndBands.length;\n while (i--) {\n if (plotLinesAndBands[i].id === id) {\n plotLinesAndBands[i].destroy();\n }\n }\n each([\n options.plotLines || [],\n userOptions.plotLines || [],\n options.plotBands || [],\n userOptions.plotBands || []\n ], function(arr) {\n i = arr.length;\n while (i--) {\n if (arr[i].id === id) {\n erase(arr, arr[i]);\n }\n }\n });\n },\n\n /**\n * Remove a plot band by its id.\n * \n * @param {String} id\n * The plot band's `id` as given in the original configuration\n * object or in the `addPlotBand` option.\n * @sample highcharts/members/axis-removeplotband/\n * Remove plot band by id\n * @sample highcharts/members/axis-addplotband/\n * Toggle the plot band from a button\n */\n removePlotBand: function(id) {\n this.removePlotBandOrLine(id);\n },\n\n /**\n * Remove a plot line by its id.\n * @param {String} id\n * The plot line's `id` as given in the original configuration\n * object or in the `addPlotLine` option.\n * @sample highcharts/xaxis/plotlines-id/\n * Remove plot line by id\n * @sample highcharts/members/axis-addplotline/\n * Toggle the plot line from a button\n */\n removePlotLine: function(id) {\n this.removePlotBandOrLine(id);\n }\n });\n\n }(Highcharts, Axis));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var dateFormat = H.dateFormat,\n each = H.each,\n extend = H.extend,\n format = H.format,\n isNumber = H.isNumber,\n map = H.map,\n merge = H.merge,\n pick = H.pick,\n splat = H.splat,\n syncTimeout = H.syncTimeout,\n timeUnits = H.timeUnits;\n /**\n * The tooltip object\n * @param {Object} chart The chart instance\n * @param {Object} options Tooltip options\n */\n H.Tooltip = function() {\n this.init.apply(this, arguments);\n };\n\n H.Tooltip.prototype = {\n\n init: function(chart, options) {\n\n // Save the chart and options\n this.chart = chart;\n this.options = options;\n\n // Keep track of the current series\n //this.currentSeries = undefined;\n\n // List of crosshairs\n this.crosshairs = [];\n\n // Current values of x and y when animating\n this.now = {\n x: 0,\n y: 0\n };\n\n // The tooltip is initially hidden\n this.isHidden = true;\n\n\n\n // Public property for getting the shared state.\n this.split = options.split && !chart.inverted;\n this.shared = options.shared || this.split;\n\n },\n\n /**\n * Destroy the single tooltips in a split tooltip.\n * If the tooltip is active then it is not destroyed, unless forced to.\n * @param {boolean} force Force destroy all tooltips.\n * @return {undefined}\n */\n cleanSplit: function(force) {\n each(this.chart.series, function(series) {\n var tt = series && series.tt;\n if (tt) {\n if (!tt.isActive || force) {\n series.tt = tt.destroy();\n } else {\n tt.isActive = false;\n }\n }\n });\n },\n\n\n\n\n /**\n * Create the Tooltip label element if it doesn't exist, then return the\n * label.\n */\n getLabel: function() {\n\n var renderer = this.chart.renderer,\n options = this.options;\n\n if (!this.label) {\n // Create the label\n if (this.split) {\n this.label = renderer.g('tooltip');\n } else {\n this.label = renderer.label(\n '',\n 0,\n 0,\n options.shape || 'callout',\n null,\n null,\n options.useHTML,\n null,\n 'tooltip'\n )\n .attr({\n padding: options.padding,\n r: options.borderRadius\n });\n\n\n this.label\n .attr({\n 'fill': options.backgroundColor,\n 'stroke-width': options.borderWidth\n })\n // #2301, #2657\n .css(options.style)\n .shadow(options.shadow);\n\n }\n\n\n\n this.label\n .attr({\n zIndex: 8\n })\n .add();\n }\n return this.label;\n },\n\n update: function(options) {\n this.destroy();\n // Update user options (#6218)\n merge(true, this.chart.options.tooltip.userOptions, options);\n this.init(this.chart, merge(true, this.options, options));\n },\n\n /**\n * Destroy the tooltip and its elements.\n */\n destroy: function() {\n // Destroy and clear local variables\n if (this.label) {\n this.label = this.label.destroy();\n }\n if (this.split && this.tt) {\n this.cleanSplit(this.chart, true);\n this.tt = this.tt.destroy();\n }\n clearTimeout(this.hideTimer);\n clearTimeout(this.tooltipTimeout);\n },\n\n /**\n * Provide a soft movement for the tooltip\n *\n * @param {Number} x\n * @param {Number} y\n * @private\n */\n move: function(x, y, anchorX, anchorY) {\n var tooltip = this,\n now = tooltip.now,\n animate = tooltip.options.animation !== false && !tooltip.isHidden &&\n // When we get close to the target position, abort animation and land on the right place (#3056)\n (Math.abs(x - now.x) > 1 || Math.abs(y - now.y) > 1),\n skipAnchor = tooltip.followPointer || tooltip.len > 1;\n\n // Get intermediate values for animation\n extend(now, {\n x: animate ? (2 * now.x + x) / 3 : x,\n y: animate ? (now.y + y) / 2 : y,\n anchorX: skipAnchor ? undefined : animate ? (2 * now.anchorX + anchorX) / 3 : anchorX,\n anchorY: skipAnchor ? undefined : animate ? (now.anchorY + anchorY) / 2 : anchorY\n });\n\n // Move to the intermediate value\n tooltip.getLabel().attr(now);\n\n\n // Run on next tick of the mouse tracker\n if (animate) {\n\n // Never allow two timeouts\n clearTimeout(this.tooltipTimeout);\n\n // Set the fixed interval ticking for the smooth tooltip\n this.tooltipTimeout = setTimeout(function() {\n // The interval function may still be running during destroy,\n // so check that the chart is really there before calling.\n if (tooltip) {\n tooltip.move(x, y, anchorX, anchorY);\n }\n }, 32);\n\n }\n },\n\n /**\n * Hide the tooltip\n */\n hide: function(delay) {\n var tooltip = this;\n clearTimeout(this.hideTimer); // disallow duplicate timers (#1728, #1766)\n delay = pick(delay, this.options.hideDelay, 500);\n if (!this.isHidden) {\n this.hideTimer = syncTimeout(function() {\n tooltip.getLabel()[delay ? 'fadeOut' : 'hide']();\n tooltip.isHidden = true;\n }, delay);\n }\n },\n\n /**\n * Extendable method to get the anchor position of the tooltip\n * from a point or set of points\n */\n getAnchor: function(points, mouseEvent) {\n var ret,\n chart = this.chart,\n inverted = chart.inverted,\n plotTop = chart.plotTop,\n plotLeft = chart.plotLeft,\n plotX = 0,\n plotY = 0,\n yAxis,\n xAxis;\n\n points = splat(points);\n\n // Pie uses a special tooltipPos\n ret = points[0].tooltipPos;\n\n // When tooltip follows mouse, relate the position to the mouse\n if (this.followPointer && mouseEvent) {\n if (mouseEvent.chartX === undefined) {\n mouseEvent = chart.pointer.normalize(mouseEvent);\n }\n ret = [\n mouseEvent.chartX - chart.plotLeft,\n mouseEvent.chartY - plotTop\n ];\n }\n // When shared, use the average position\n if (!ret) {\n each(points, function(point) {\n yAxis = point.series.yAxis;\n xAxis = point.series.xAxis;\n plotX += point.plotX + (!inverted && xAxis ? xAxis.left - plotLeft : 0);\n plotY += (point.plotLow ? (point.plotLow + point.plotHigh) / 2 : point.plotY) +\n (!inverted && yAxis ? yAxis.top - plotTop : 0); // #1151\n });\n\n plotX /= points.length;\n plotY /= points.length;\n\n ret = [\n inverted ? chart.plotWidth - plotY : plotX,\n this.shared && !inverted && points.length > 1 && mouseEvent ?\n mouseEvent.chartY - plotTop : // place shared tooltip next to the mouse (#424)\n inverted ? chart.plotHeight - plotX : plotY\n ];\n }\n\n return map(ret, Math.round);\n },\n\n /**\n * Place the tooltip in a chart without spilling over\n * and not covering the point it self.\n */\n getPosition: function(boxWidth, boxHeight, point) {\n\n var chart = this.chart,\n distance = this.distance,\n ret = {},\n h = point.h || 0, // #4117\n swapped,\n first = ['y', chart.chartHeight, boxHeight,\n point.plotY + chart.plotTop, chart.plotTop,\n chart.plotTop + chart.plotHeight\n ],\n second = ['x', chart.chartWidth, boxWidth,\n point.plotX + chart.plotLeft, chart.plotLeft,\n chart.plotLeft + chart.plotWidth\n ],\n // The far side is right or bottom\n preferFarSide = !this.followPointer && pick(point.ttBelow, !chart.inverted === !!point.negative), // #4984\n /**\n * Handle the preferred dimension. When the preferred dimension is tooltip\n * on top or bottom of the point, it will look for space there.\n */\n firstDimension = function(dim, outerSize, innerSize, point, min, max) {\n var roomLeft = innerSize < point - distance,\n roomRight = point + distance + innerSize < outerSize,\n alignedLeft = point - distance - innerSize,\n alignedRight = point + distance;\n\n if (preferFarSide && roomRight) {\n ret[dim] = alignedRight;\n } else if (!preferFarSide && roomLeft) {\n ret[dim] = alignedLeft;\n } else if (roomLeft) {\n ret[dim] = Math.min(max - innerSize, alignedLeft - h < 0 ? alignedLeft : alignedLeft - h);\n } else if (roomRight) {\n ret[dim] = Math.max(\n min,\n alignedRight + h + innerSize > outerSize ?\n alignedRight :\n alignedRight + h\n );\n } else {\n return false;\n }\n },\n /**\n * Handle the secondary dimension. If the preferred dimension is tooltip\n * on top or bottom of the point, the second dimension is to align the tooltip\n * above the point, trying to align center but allowing left or right\n * align within the chart box.\n */\n secondDimension = function(dim, outerSize, innerSize, point) {\n var retVal;\n\n // Too close to the edge, return false and swap dimensions\n if (point < distance || point > outerSize - distance) {\n retVal = false;\n // Align left/top\n } else if (point < innerSize / 2) {\n ret[dim] = 1;\n // Align right/bottom\n } else if (point > outerSize - innerSize / 2) {\n ret[dim] = outerSize - innerSize - 2;\n // Align center\n } else {\n ret[dim] = point - innerSize / 2;\n }\n return retVal;\n },\n /**\n * Swap the dimensions\n */\n swap = function(count) {\n var temp = first;\n first = second;\n second = temp;\n swapped = count;\n },\n run = function() {\n if (firstDimension.apply(0, first) !== false) {\n if (secondDimension.apply(0, second) === false && !swapped) {\n swap(true);\n run();\n }\n } else if (!swapped) {\n swap(true);\n run();\n } else {\n ret.x = ret.y = 0;\n }\n };\n\n // Under these conditions, prefer the tooltip on the side of the point\n if (chart.inverted || this.len > 1) {\n swap();\n }\n run();\n\n return ret;\n\n },\n\n /**\n * In case no user defined formatter is given, this will be used. Note that the context\n * here is an object holding point, series, x, y etc.\n *\n * @returns {String|Array}\n */\n defaultFormatter: function(tooltip) {\n var items = this.points || splat(this),\n s;\n\n // Build the header\n s = [tooltip.tooltipFooterHeaderFormatter(items[0])];\n\n // build the values\n s = s.concat(tooltip.bodyFormatter(items));\n\n // footer\n s.push(tooltip.tooltipFooterHeaderFormatter(items[0], true));\n\n return s;\n },\n\n /**\n * Refresh the tooltip's text and position.\n * @param {Object|Array} pointOrPoints Rither a point or an array of points\n */\n refresh: function(pointOrPoints, mouseEvent) {\n var tooltip = this,\n label,\n options = tooltip.options,\n x,\n y,\n point = pointOrPoints,\n anchor,\n textConfig = {},\n text,\n pointConfig = [],\n formatter = options.formatter || tooltip.defaultFormatter,\n shared = tooltip.shared,\n currentSeries;\n\n clearTimeout(this.hideTimer);\n\n // get the reference point coordinates (pie charts use tooltipPos)\n tooltip.followPointer = splat(point)[0].series.tooltipOptions.followPointer;\n anchor = tooltip.getAnchor(point, mouseEvent);\n x = anchor[0];\n y = anchor[1];\n\n // shared tooltip, array is sent over\n if (shared && !(point.series && point.series.noSharedTooltip)) {\n each(point, function(item) {\n item.setState('hover');\n\n pointConfig.push(item.getLabelConfig());\n });\n\n textConfig = {\n x: point[0].category,\n y: point[0].y\n };\n textConfig.points = pointConfig;\n point = point[0];\n\n // single point tooltip\n } else {\n textConfig = point.getLabelConfig();\n }\n this.len = pointConfig.length; // #6128\n text = formatter.call(textConfig, tooltip);\n\n // register the current series\n currentSeries = point.series;\n this.distance = pick(currentSeries.tooltipOptions.distance, 16);\n\n // update the inner HTML\n if (text === false) {\n this.hide();\n } else {\n\n label = tooltip.getLabel();\n\n // show it\n if (tooltip.isHidden) {\n label.attr({\n opacity: 1\n }).show();\n }\n\n // update text\n if (tooltip.split) {\n this.renderSplit(text, pointOrPoints);\n } else {\n\n // Prevent the tooltip from flowing over the chart box (#6659)\n\n if (!options.style.width) {\n\n label.css({\n width: this.chart.spacingBox.width\n });\n\n }\n\n\n label.attr({\n text: text && text.join ? text.join('') : text\n });\n\n // Set the stroke color of the box to reflect the point\n label.removeClass(/highcharts-color-[\\d]+/g)\n .addClass('highcharts-color-' + pick(point.colorIndex, currentSeries.colorIndex));\n\n\n label.attr({\n stroke: options.borderColor || point.color || currentSeries.color || '#666666'\n });\n\n\n tooltip.updatePosition({\n plotX: x,\n plotY: y,\n negative: point.negative,\n ttBelow: point.ttBelow,\n h: anchor[2] || 0\n });\n }\n\n this.isHidden = false;\n }\n },\n\n /**\n * Render the split tooltip. Loops over each point's text and adds\n * a label next to the point, then uses the distribute function to \n * find best non-overlapping positions.\n */\n renderSplit: function(labels, points) {\n var tooltip = this,\n boxes = [],\n chart = this.chart,\n ren = chart.renderer,\n rightAligned = true,\n options = this.options,\n headerHeight,\n tooltipLabel = this.getLabel();\n\n // Create the individual labels for header and points, ignore footer\n each(labels.slice(0, points.length + 1), function(str, i) {\n var point = points[i - 1] ||\n // Item 0 is the header. Instead of this, we could also use the crosshair label\n {\n isHeader: true,\n plotX: points[0].plotX\n },\n owner = point.series || tooltip,\n tt = owner.tt,\n series = point.series || {},\n colorClass = 'highcharts-color-' + pick(point.colorIndex, series.colorIndex, 'none'),\n target,\n x,\n bBox,\n boxWidth;\n\n // Store the tooltip referance on the series\n if (!tt) {\n owner.tt = tt = ren.label(null, null, null, 'callout')\n .addClass('highcharts-tooltip-box ' + colorClass)\n .attr({\n 'padding': options.padding,\n 'r': options.borderRadius,\n\n 'fill': options.backgroundColor,\n 'stroke': point.color || series.color || '#333333',\n 'stroke-width': options.borderWidth\n\n })\n .add(tooltipLabel);\n }\n\n tt.isActive = true;\n tt.attr({\n text: str\n });\n\n tt.css(options.style);\n\n\n // Get X position now, so we can move all to the other side in case of overflow\n bBox = tt.getBBox();\n boxWidth = bBox.width + tt.strokeWidth();\n if (point.isHeader) {\n headerHeight = bBox.height;\n x = Math.max(\n 0, // No left overflow\n Math.min(\n point.plotX + chart.plotLeft - boxWidth / 2,\n chart.chartWidth - boxWidth // No right overflow (#5794)\n )\n );\n } else {\n x = point.plotX + chart.plotLeft - pick(options.distance, 16) -\n boxWidth;\n }\n\n\n // If overflow left, we don't use this x in the next loop\n if (x < 0) {\n rightAligned = false;\n }\n\n // Prepare for distribution\n target = (point.series && point.series.yAxis && point.series.yAxis.pos) + (point.plotY || 0);\n target -= chart.plotTop;\n boxes.push({\n target: point.isHeader ? chart.plotHeight + headerHeight : target,\n rank: point.isHeader ? 1 : 0,\n size: owner.tt.getBBox().height + 1,\n point: point,\n x: x,\n tt: tt\n });\n });\n\n // Clean previous run (for missing points)\n this.cleanSplit();\n\n // Distribute and put in place\n H.distribute(boxes, chart.plotHeight + headerHeight);\n each(boxes, function(box) {\n var point = box.point,\n series = point.series;\n\n // Put the label in place\n box.tt.attr({\n visibility: box.pos === undefined ? 'hidden' : 'inherit',\n x: (rightAligned || point.isHeader ?\n box.x :\n point.plotX + chart.plotLeft + pick(options.distance, 16)),\n y: box.pos + chart.plotTop,\n anchorX: point.isHeader ?\n point.plotX + chart.plotLeft : point.plotX + series.xAxis.pos,\n anchorY: point.isHeader ?\n box.pos + chart.plotTop - 15 : point.plotY + series.yAxis.pos\n });\n });\n },\n\n /**\n * Find the new position and perform the move\n */\n updatePosition: function(point) {\n var chart = this.chart,\n label = this.getLabel(),\n pos = (this.options.positioner || this.getPosition).call(\n this,\n label.width,\n label.height,\n point\n );\n\n // do the move\n this.move(\n Math.round(pos.x),\n Math.round(pos.y || 0), // can be undefined (#3977) \n point.plotX + chart.plotLeft,\n point.plotY + chart.plotTop\n );\n },\n\n /**\n * Get the optimal date format for a point, based on a range.\n * @param {number} range - The time range\n * @param {number|Date} date - The date of the point in question\n * @param {number} startOfWeek - An integer representing the first day of\n * the week, where 0 is Sunday\n * @param {Object} dateTimeLabelFormats - A map of time units to formats\n * @return {string} - the optimal date format for a point\n */\n getDateFormat: function(range, date, startOfWeek, dateTimeLabelFormats) {\n var dateStr = dateFormat('%m-%d %H:%M:%S.%L', date),\n format,\n n,\n blank = '01-01 00:00:00.000',\n strpos = {\n millisecond: 15,\n second: 12,\n minute: 9,\n hour: 6,\n day: 3\n },\n lastN = 'millisecond'; // for sub-millisecond data, #4223\n for (n in timeUnits) {\n\n // If the range is exactly one week and we're looking at a Sunday/Monday, go for the week format\n if (range === timeUnits.week && +dateFormat('%w', date) === startOfWeek &&\n dateStr.substr(6) === blank.substr(6)) {\n n = 'week';\n break;\n }\n\n // The first format that is too great for the range\n if (timeUnits[n] > range) {\n n = lastN;\n break;\n }\n\n // If the point is placed every day at 23:59, we need to show\n // the minutes as well. #2637.\n if (strpos[n] && dateStr.substr(strpos[n]) !== blank.substr(strpos[n])) {\n break;\n }\n\n // Weeks are outside the hierarchy, only apply them on Mondays/Sundays like in the first condition\n if (n !== 'week') {\n lastN = n;\n }\n }\n\n if (n) {\n format = dateTimeLabelFormats[n];\n }\n\n return format;\n },\n\n /**\n * Get the best X date format based on the closest point range on the axis.\n */\n getXDateFormat: function(point, options, xAxis) {\n var xDateFormat,\n dateTimeLabelFormats = options.dateTimeLabelFormats,\n closestPointRange = xAxis && xAxis.closestPointRange;\n\n if (closestPointRange) {\n xDateFormat = this.getDateFormat(\n closestPointRange,\n point.x,\n xAxis.options.startOfWeek,\n dateTimeLabelFormats\n );\n } else {\n xDateFormat = dateTimeLabelFormats.day;\n }\n\n return xDateFormat || dateTimeLabelFormats.year; // #2546, 2581\n },\n\n /**\n * Format the footer/header of the tooltip\n * #3397: abstraction to enable formatting of footer and header\n */\n tooltipFooterHeaderFormatter: function(labelConfig, isFooter) {\n var footOrHead = isFooter ? 'footer' : 'header',\n series = labelConfig.series,\n tooltipOptions = series.tooltipOptions,\n xDateFormat = tooltipOptions.xDateFormat,\n xAxis = series.xAxis,\n isDateTime = xAxis && xAxis.options.type === 'datetime' && isNumber(labelConfig.key),\n formatString = tooltipOptions[footOrHead + 'Format'];\n\n // Guess the best date format based on the closest point distance (#568, #3418)\n if (isDateTime && !xDateFormat) {\n xDateFormat = this.getXDateFormat(labelConfig, tooltipOptions, xAxis);\n }\n\n // Insert the footer date format if any\n if (isDateTime && xDateFormat) {\n formatString = formatString.replace('{point.key}', '{point.key:' + xDateFormat + '}');\n }\n\n return format(formatString, {\n point: labelConfig,\n series: series\n });\n },\n\n /**\n * Build the body (lines) of the tooltip by iterating over the items and returning one entry for each item,\n * abstracting this functionality allows to easily overwrite and extend it.\n */\n bodyFormatter: function(items) {\n return map(items, function(item) {\n var tooltipOptions = item.series.tooltipOptions;\n return (tooltipOptions.pointFormatter || item.point.tooltipFormatter)\n .call(item.point, tooltipOptions.pointFormat);\n });\n }\n\n };\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var addEvent = H.addEvent,\n attr = H.attr,\n charts = H.charts,\n color = H.color,\n css = H.css,\n defined = H.defined,\n doc = H.doc,\n each = H.each,\n extend = H.extend,\n fireEvent = H.fireEvent,\n offset = H.offset,\n pick = H.pick,\n removeEvent = H.removeEvent,\n splat = H.splat,\n Tooltip = H.Tooltip,\n win = H.win;\n\n /**\n * The mouse tracker object. All methods starting with \"on\" are primary DOM\n * event handlers. Subsequent methods should be named differently from what they\n * are doing.\n *\n * @constructor Pointer\n * @param {Object} chart The Chart instance\n * @param {Object} options The root options object\n */\n H.Pointer = function(chart, options) {\n this.init(chart, options);\n };\n\n H.Pointer.prototype = {\n /**\n * Initialize Pointer\n */\n init: function(chart, options) {\n\n // Store references\n this.options = options;\n this.chart = chart;\n\n // Do we need to handle click on a touch device?\n this.runChartClick = options.chart.events && !!options.chart.events.click;\n\n this.pinchDown = [];\n this.lastValidTouch = {};\n\n if (Tooltip && options.tooltip.enabled) {\n chart.tooltip = new Tooltip(chart, options.tooltip);\n this.followTouchMove = pick(options.tooltip.followTouchMove, true);\n }\n\n this.setDOMEvents();\n },\n\n /**\n * Resolve the zoomType option, this is reset on all touch start and mouse\n * down events.\n */\n zoomOption: function(e) {\n var chart = this.chart,\n options = chart.options.chart,\n zoomType = options.zoomType || '',\n inverted = chart.inverted,\n zoomX,\n zoomY;\n\n // Look for the pinchType option\n if (/touch/.test(e.type)) {\n zoomType = pick(options.pinchType, zoomType);\n }\n\n this.zoomX = zoomX = /x/.test(zoomType);\n this.zoomY = zoomY = /y/.test(zoomType);\n this.zoomHor = (zoomX && !inverted) || (zoomY && inverted);\n this.zoomVert = (zoomY && !inverted) || (zoomX && inverted);\n this.hasZoom = zoomX || zoomY;\n },\n\n /**\n * @typedef {Object} PointerEvent\n * A native browser mouse or touch event, extended with position\n * information relative to the {@link Chart.container}.\n * @property {Number} chartX\n * The X coordinate of the pointer interaction relative to the\n * chart.\n * @property {Number} chartY\n * The Y coordinate of the pointer interaction relative to the \n * chart.\n * \n */\n /**\n * Add crossbrowser support for chartX and chartY.\n * \n * @param {Object} e\n * The event object in standard browsers.\n *\n * @return {PointerEvent}\n * A browser event with extended properties `chartX` and `chartY`\n */\n normalize: function(e, chartPosition) {\n var chartX,\n chartY,\n ePos;\n\n // IE normalizing\n e = e || win.event;\n if (!e.target) {\n e.target = e.srcElement;\n }\n\n // iOS (#2757)\n ePos = e.touches ? (e.touches.length ? e.touches.item(0) : e.changedTouches[0]) : e;\n\n // Get mouse position\n if (!chartPosition) {\n this.chartPosition = chartPosition = offset(this.chart.container);\n }\n\n // chartX and chartY\n if (ePos.pageX === undefined) { // IE < 9. #886.\n chartX = Math.max(e.x, e.clientX - chartPosition.left); // #2005, #2129: the second case is \n // for IE10 quirks mode within framesets\n chartY = e.y;\n } else {\n chartX = ePos.pageX - chartPosition.left;\n chartY = ePos.pageY - chartPosition.top;\n }\n\n return extend(e, {\n chartX: Math.round(chartX),\n chartY: Math.round(chartY)\n });\n },\n\n /**\n * Get the click position in terms of axis values.\n *\n * @param {Object} e A pointer event\n */\n getCoordinates: function(e) {\n var coordinates = {\n xAxis: [],\n yAxis: []\n };\n\n each(this.chart.axes, function(axis) {\n coordinates[axis.isXAxis ? 'xAxis' : 'yAxis'].push({\n axis: axis,\n value: axis.toValue(e[axis.horiz ? 'chartX' : 'chartY'])\n });\n });\n return coordinates;\n },\n /**\n * Collects the points closest to a mouseEvent\n * @param {Array} series Array of series to gather points from\n * @param {Boolean} shared True if shared tooltip, otherwise false\n * @param {Object} e Mouse event which possess a position to compare against\n * @return {Array} KDPoints sorted by distance\n */\n getKDPoints: function(series, shared, e) {\n var kdpoints = [],\n noSharedTooltip,\n directTouch,\n kdpointT,\n i;\n\n // Find nearest points on all series\n each(series, function(s) {\n // Skip hidden series\n noSharedTooltip = s.noSharedTooltip && shared;\n directTouch = !shared && s.directTouch;\n if (s.visible && !directTouch && pick(s.options.enableMouseTracking, true)) { // #3821\n // #3828\n kdpointT = s.searchPoint(\n e, !noSharedTooltip && s.options.findNearestPointBy.indexOf('y') < 0\n );\n if (kdpointT && kdpointT.series) { // Point.series becomes null when reset and before redraw (#5197)\n kdpoints.push(kdpointT);\n }\n }\n });\n\n // Sort kdpoints by distance to mouse pointer\n kdpoints.sort(function(p1, p2) {\n var isCloserX = p1.distX - p2.distX,\n isCloser = p1.dist - p2.dist,\n isAbove =\n (p2.series.group && p2.series.group.zIndex) -\n (p1.series.group && p1.series.group.zIndex),\n result;\n\n // We have two points which are not in the same place on xAxis and shared tooltip:\n if (isCloserX !== 0 && shared) { // #5721\n result = isCloserX;\n // Points are not exactly in the same place on x/yAxis:\n } else if (isCloser !== 0) {\n result = isCloser;\n // The same xAxis and yAxis position, sort by z-index:\n } else if (isAbove !== 0) {\n result = isAbove;\n // The same zIndex, sort by array index:\n } else {\n result = p1.series.index > p2.series.index ? -1 : 1;\n }\n return result;\n });\n\n // Remove points with different x-positions, required for shared tooltip and crosshairs (#4645):\n if (shared && kdpoints[0] && !kdpoints[0].series.noSharedTooltip) {\n i = kdpoints.length;\n while (i--) {\n if (kdpoints[i].x !== kdpoints[0].x || kdpoints[i].series.noSharedTooltip) {\n kdpoints.splice(i, 1);\n }\n }\n }\n return kdpoints;\n },\n getPointFromEvent: function(e) {\n var target = e.target,\n point;\n\n while (target && !point) {\n point = target.point;\n target = target.parentNode;\n }\n return point;\n },\n\n getChartCoordinatesFromPoint: function(point, inverted) {\n var series = point.series,\n xAxis = series.xAxis,\n yAxis = series.yAxis;\n\n if (xAxis && yAxis) {\n return inverted ? {\n chartX: xAxis.len + xAxis.pos - point.clientX,\n chartY: yAxis.len + yAxis.pos - point.plotY\n } : {\n chartX: point.clientX + xAxis.pos,\n chartY: point.plotY + yAxis.pos\n };\n }\n },\n\n /**\n * Calculates what is the current hovered point/points and series.\n *\n * @private\n *\n * @param {undefined|Point} existingHoverPoint\n * The point currrently beeing hovered.\n * @param {undefined|Series} existingHoverSeries\n * The series currently beeing hovered.\n * @param {Array<.Series>} series\n * All the series in the chart.\n * @param {boolean} isDirectTouch\n * Is the pointer directly hovering the point.\n * @param {boolean} shared\n * Whether it is a shared tooltip or not.\n * @param {object} coordinates\n * Chart coordinates of the pointer.\n * @param {number} coordinates.chartX\n * @param {number} coordinates.chartY\n * \n * @return {object}\n * Object containing resulting hover data.\n */\n getHoverData: function(\n existingHoverPoint,\n existingHoverSeries,\n series,\n isDirectTouch,\n shared,\n coordinates\n ) {\n var hoverPoint = existingHoverPoint,\n hoverSeries = existingHoverSeries,\n searchSeries = shared ? series : [hoverSeries],\n useExisting = !!(isDirectTouch && existingHoverPoint),\n notSticky = hoverSeries && !hoverSeries.stickyTracking,\n isHoverPoint = function(point, i) {\n return i === 0;\n },\n hoverPoints;\n\n // If there is a hoverPoint and its series requires direct touch (like\n // columns, #3899), or we're on a noSharedTooltip series among shared\n // tooltip series (#4546), use the existing hoverPoint.\n if (useExisting) {\n isHoverPoint = function(p) {\n return p === existingHoverPoint;\n };\n } else if (notSticky) {\n isHoverPoint = function(p) {\n return p.series === hoverSeries;\n };\n } else {\n // Avoid series with stickyTracking false\n searchSeries = H.grep(series, function(s) {\n return s.stickyTracking;\n });\n }\n hoverPoints = (useExisting && !shared) ?\n // Non-shared tooltips with directTouch don't use the k-d-tree\n [existingHoverPoint] :\n this.getKDPoints(searchSeries, shared, coordinates);\n hoverPoint = H.find(hoverPoints, isHoverPoint);\n hoverSeries = hoverPoint && hoverPoint.series;\n\n // In this case we could only look for the hoverPoint in series with\n // stickyTracking, but we should still include all series in the shared\n // tooltip.\n if (!useExisting && !notSticky && shared) {\n hoverPoints = this.getKDPoints(series, shared, coordinates);\n }\n // Keep the order of series in tooltip\n // Must be done after assigning of hoverPoint\n hoverPoints.sort(function(p1, p2) {\n return p1.series.index - p2.series.index;\n });\n\n return {\n hoverPoint: hoverPoint,\n hoverSeries: hoverSeries,\n hoverPoints: hoverPoints\n };\n },\n /**\n * With line type charts with a single tracker, get the point closest to the mouse.\n * Run Point.onMouseOver and display tooltip for the point or points.\n */\n runPointActions: function(e, p) {\n var pointer = this,\n chart = pointer.chart,\n series = chart.series,\n tooltip = chart.tooltip,\n shared = tooltip ? tooltip.shared : false,\n hoverPoint = p || chart.hoverPoint,\n hoverSeries = hoverPoint && hoverPoint.series || chart.hoverSeries,\n // onMouseOver or already hovering a series with directTouch\n isDirectTouch = !!p || (\n (hoverSeries && hoverSeries.directTouch) &&\n pointer.isDirectTouch\n ),\n hoverData = this.getHoverData(\n hoverPoint,\n hoverSeries,\n series,\n isDirectTouch,\n shared,\n e\n ),\n useSharedTooltip,\n followPointer,\n anchor,\n points;\n // Update variables from hoverData.\n hoverPoint = hoverData.hoverPoint;\n hoverSeries = hoverData.hoverSeries;\n followPointer = hoverSeries && hoverSeries.tooltipOptions.followPointer;\n useSharedTooltip = (\n shared &&\n hoverPoint &&\n !hoverPoint.series.noSharedTooltip\n );\n points = (useSharedTooltip ?\n hoverData.hoverPoints :\n (hoverPoint ? [hoverPoint] : [])\n );\n // Refresh tooltip for kdpoint if new hover point or tooltip was hidden\n // #3926, #4200\n if (\n hoverPoint &&\n // !(hoverSeries && hoverSeries.directTouch) &&\n (hoverPoint !== chart.hoverPoint || (tooltip && tooltip.isHidden))\n ) {\n each(chart.hoverPoints || [], function(p) {\n if (H.inArray(p, points) === -1) {\n p.setState();\n }\n });\n // Do mouseover on all points (#3919, #3985, #4410, #5622)\n each(points || [], function(p) {\n p.setState('hover');\n });\n // set normal state to previous series\n if (chart.hoverSeries !== hoverSeries) {\n hoverSeries.onMouseOver();\n }\n\n // If tracking is on series in stead of on each point, \n // fire mouseOver on hover point. // #4448\n if (chart.hoverPoint) {\n chart.hoverPoint.firePointEvent('mouseOut');\n }\n hoverPoint.firePointEvent('mouseOver');\n chart.hoverPoints = points;\n chart.hoverPoint = hoverPoint;\n // Draw tooltip if necessary\n if (tooltip) {\n tooltip.refresh(useSharedTooltip ? points : hoverPoint, e);\n }\n // Update positions (regardless of kdpoint or hoverPoint)\n } else if (followPointer && tooltip && !tooltip.isHidden) {\n anchor = tooltip.getAnchor([{}], e);\n tooltip.updatePosition({\n plotX: anchor[0],\n plotY: anchor[1]\n });\n }\n\n // Start the event listener to pick up the tooltip and crosshairs\n if (!pointer.unDocMouseMove) {\n pointer.unDocMouseMove = addEvent(doc, 'mousemove', function(e) {\n var chart = charts[H.hoverChartIndex];\n if (chart) {\n chart.pointer.onDocumentMouseMove(e);\n }\n });\n }\n\n // Issues related to crosshair #4927, #5269 #5066, #5658\n each(chart.axes, function drawAxisCrosshair(axis) {\n var snap = pick(axis.crosshair.snap, true);\n if (!snap) {\n axis.drawCrosshair(e);\n\n // Axis has snapping crosshairs, and one of the hover points belongs\n // to axis\n } else if (H.find(points, function(p) {\n return p.series[axis.coll] === axis;\n })) {\n axis.drawCrosshair(e, hoverPoint);\n // Axis has snapping crosshairs, but no hover point belongs to axis\n } else {\n axis.hideCrosshair();\n }\n });\n },\n\n /**\n * Reset the tracking by hiding the tooltip, the hover series state and the\n * hover point\n *\n * @param allowMove {Boolean}\n * Instead of destroying the tooltip altogether, allow moving it if\n * possible\n */\n reset: function(allowMove, delay) {\n var pointer = this,\n chart = pointer.chart,\n hoverSeries = chart.hoverSeries,\n hoverPoint = chart.hoverPoint,\n hoverPoints = chart.hoverPoints,\n tooltip = chart.tooltip,\n tooltipPoints = tooltip && tooltip.shared ? hoverPoints : hoverPoint;\n\n // Check if the points have moved outside the plot area (#1003, #4736, #5101)\n if (allowMove && tooltipPoints) {\n each(splat(tooltipPoints), function(point) {\n if (point.series.isCartesian && point.plotX === undefined) {\n allowMove = false;\n }\n });\n }\n\n // Just move the tooltip, #349\n if (allowMove) {\n if (tooltip && tooltipPoints) {\n tooltip.refresh(tooltipPoints);\n if (hoverPoint) { // #2500\n hoverPoint.setState(hoverPoint.state, true);\n each(chart.axes, function(axis) {\n if (axis.crosshair) {\n axis.drawCrosshair(null, hoverPoint);\n }\n });\n }\n }\n\n // Full reset\n } else {\n\n if (hoverPoint) {\n hoverPoint.onMouseOut();\n }\n\n if (hoverPoints) {\n each(hoverPoints, function(point) {\n point.setState();\n });\n }\n\n if (hoverSeries) {\n hoverSeries.onMouseOut();\n }\n\n if (tooltip) {\n tooltip.hide(delay);\n }\n\n if (pointer.unDocMouseMove) {\n pointer.unDocMouseMove = pointer.unDocMouseMove();\n }\n\n // Remove crosshairs\n each(chart.axes, function(axis) {\n axis.hideCrosshair();\n });\n\n pointer.hoverX = chart.hoverPoints = chart.hoverPoint = null;\n }\n },\n\n /**\n * Scale series groups to a certain scale and translation\n */\n scaleGroups: function(attribs, clip) {\n\n var chart = this.chart,\n seriesAttribs;\n\n // Scale each series\n each(chart.series, function(series) {\n seriesAttribs = attribs || series.getPlotBox(); // #1701\n if (series.xAxis && series.xAxis.zoomEnabled && series.group) {\n series.group.attr(seriesAttribs);\n if (series.markerGroup) {\n series.markerGroup.attr(seriesAttribs);\n series.markerGroup.clip(clip ? chart.clipRect : null);\n }\n if (series.dataLabelsGroup) {\n series.dataLabelsGroup.attr(seriesAttribs);\n }\n }\n });\n\n // Clip\n chart.clipRect.attr(clip || chart.clipBox);\n },\n\n /**\n * Start a drag operation\n */\n dragStart: function(e) {\n var chart = this.chart;\n\n // Record the start position\n chart.mouseIsDown = e.type;\n chart.cancelClick = false;\n chart.mouseDownX = this.mouseDownX = e.chartX;\n chart.mouseDownY = this.mouseDownY = e.chartY;\n },\n\n /**\n * Perform a drag operation in response to a mousemove event while the mouse is down\n */\n drag: function(e) {\n\n var chart = this.chart,\n chartOptions = chart.options.chart,\n chartX = e.chartX,\n chartY = e.chartY,\n zoomHor = this.zoomHor,\n zoomVert = this.zoomVert,\n plotLeft = chart.plotLeft,\n plotTop = chart.plotTop,\n plotWidth = chart.plotWidth,\n plotHeight = chart.plotHeight,\n clickedInside,\n size,\n selectionMarker = this.selectionMarker,\n mouseDownX = this.mouseDownX,\n mouseDownY = this.mouseDownY,\n panKey = chartOptions.panKey && e[chartOptions.panKey + 'Key'];\n\n // If the device supports both touch and mouse (like IE11), and we are touch-dragging\n // inside the plot area, don't handle the mouse event. #4339.\n if (selectionMarker && selectionMarker.touch) {\n return;\n }\n\n // If the mouse is outside the plot area, adjust to cooordinates\n // inside to prevent the selection marker from going outside\n if (chartX < plotLeft) {\n chartX = plotLeft;\n } else if (chartX > plotLeft + plotWidth) {\n chartX = plotLeft + plotWidth;\n }\n\n if (chartY < plotTop) {\n chartY = plotTop;\n } else if (chartY > plotTop + plotHeight) {\n chartY = plotTop + plotHeight;\n }\n\n // determine if the mouse has moved more than 10px\n this.hasDragged = Math.sqrt(\n Math.pow(mouseDownX - chartX, 2) +\n Math.pow(mouseDownY - chartY, 2)\n );\n\n if (this.hasDragged > 10) {\n clickedInside = chart.isInsidePlot(mouseDownX - plotLeft, mouseDownY - plotTop);\n\n // make a selection\n if (chart.hasCartesianSeries && (this.zoomX || this.zoomY) && clickedInside && !panKey) {\n if (!selectionMarker) {\n this.selectionMarker = selectionMarker = chart.renderer.rect(\n plotLeft,\n plotTop,\n zoomHor ? 1 : plotWidth,\n zoomVert ? 1 : plotHeight,\n 0\n )\n .attr({\n\n fill: chartOptions.selectionMarkerFill || color('#335cad').setOpacity(0.25).get(),\n\n 'class': 'highcharts-selection-marker',\n 'zIndex': 7\n })\n .add();\n }\n }\n\n // adjust the width of the selection marker\n if (selectionMarker && zoomHor) {\n size = chartX - mouseDownX;\n selectionMarker.attr({\n width: Math.abs(size),\n x: (size > 0 ? 0 : size) + mouseDownX\n });\n }\n // adjust the height of the selection marker\n if (selectionMarker && zoomVert) {\n size = chartY - mouseDownY;\n selectionMarker.attr({\n height: Math.abs(size),\n y: (size > 0 ? 0 : size) + mouseDownY\n });\n }\n\n // panning\n if (clickedInside && !selectionMarker && chartOptions.panning) {\n chart.pan(e, chartOptions.panning);\n }\n }\n },\n\n /**\n * On mouse up or touch end across the entire document, drop the selection.\n */\n drop: function(e) {\n var pointer = this,\n chart = this.chart,\n hasPinched = this.hasPinched;\n\n if (this.selectionMarker) {\n var selectionData = {\n originalEvent: e, // #4890\n xAxis: [],\n yAxis: []\n },\n selectionBox = this.selectionMarker,\n selectionLeft = selectionBox.attr ? selectionBox.attr('x') : selectionBox.x,\n selectionTop = selectionBox.attr ? selectionBox.attr('y') : selectionBox.y,\n selectionWidth = selectionBox.attr ? selectionBox.attr('width') : selectionBox.width,\n selectionHeight = selectionBox.attr ? selectionBox.attr('height') : selectionBox.height,\n runZoom;\n\n // a selection has been made\n if (this.hasDragged || hasPinched) {\n\n // record each axis' min and max\n each(chart.axes, function(axis) {\n if (axis.zoomEnabled && defined(axis.min) && (hasPinched || pointer[{\n xAxis: 'zoomX',\n yAxis: 'zoomY'\n }[axis.coll]])) { // #859, #3569\n var horiz = axis.horiz,\n minPixelPadding = e.type === 'touchend' ? axis.minPixelPadding : 0, // #1207, #3075\n selectionMin = axis.toValue((horiz ? selectionLeft : selectionTop) + minPixelPadding),\n selectionMax = axis.toValue((horiz ? selectionLeft + selectionWidth : selectionTop + selectionHeight) - minPixelPadding);\n\n selectionData[axis.coll].push({\n axis: axis,\n min: Math.min(selectionMin, selectionMax), // for reversed axes\n max: Math.max(selectionMin, selectionMax)\n });\n runZoom = true;\n }\n });\n if (runZoom) {\n fireEvent(chart, 'selection', selectionData, function(args) {\n chart.zoom(extend(args, hasPinched ? {\n animation: false\n } : null));\n });\n }\n\n }\n this.selectionMarker = this.selectionMarker.destroy();\n\n // Reset scaling preview\n if (hasPinched) {\n this.scaleGroups();\n }\n }\n\n // Reset all\n if (chart) { // it may be destroyed on mouse up - #877\n css(chart.container, {\n cursor: chart._cursor\n });\n chart.cancelClick = this.hasDragged > 10; // #370\n chart.mouseIsDown = this.hasDragged = this.hasPinched = false;\n this.pinchDown = [];\n }\n },\n\n onContainerMouseDown: function(e) {\n\n e = this.normalize(e);\n\n this.zoomOption(e);\n\n // issue #295, dragging not always working in Firefox\n if (e.preventDefault) {\n e.preventDefault();\n }\n\n this.dragStart(e);\n },\n\n\n\n onDocumentMouseUp: function(e) {\n if (charts[H.hoverChartIndex]) {\n charts[H.hoverChartIndex].pointer.drop(e);\n }\n },\n\n /**\n * Special handler for mouse move that will hide the tooltip when the mouse leaves the plotarea.\n * Issue #149 workaround. The mouseleave event does not always fire.\n */\n onDocumentMouseMove: function(e) {\n var chart = this.chart,\n chartPosition = this.chartPosition;\n\n e = this.normalize(e, chartPosition);\n\n // If we're outside, hide the tooltip\n if (chartPosition && !this.inClass(e.target, 'highcharts-tracker') &&\n !chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) {\n this.reset();\n }\n },\n\n /**\n * When mouse leaves the container, hide the tooltip.\n */\n onContainerMouseLeave: function(e) {\n var chart = charts[H.hoverChartIndex];\n if (chart && (e.relatedTarget || e.toElement)) { // #4886, MS Touch end fires mouseleave but with no related target\n chart.pointer.reset();\n chart.pointer.chartPosition = null; // also reset the chart position, used in #149 fix\n }\n },\n\n // The mousemove, touchmove and touchstart event handler\n onContainerMouseMove: function(e) {\n\n var chart = this.chart;\n\n if (!defined(H.hoverChartIndex) || !charts[H.hoverChartIndex] || !charts[H.hoverChartIndex].mouseIsDown) {\n H.hoverChartIndex = chart.index;\n }\n\n e = this.normalize(e);\n e.returnValue = false; // #2251, #3224\n\n if (chart.mouseIsDown === 'mousedown') {\n this.drag(e);\n }\n\n // Show the tooltip and run mouse over events (#977)\n if ((this.inClass(e.target, 'highcharts-tracker') ||\n chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) && !chart.openMenu) {\n this.runPointActions(e);\n }\n },\n\n /**\n * Utility to detect whether an element has, or has a parent with, a specific\n * class name. Used on detection of tracker objects and on deciding whether\n * hovering the tooltip should cause the active series to mouse out.\n */\n inClass: function(element, className) {\n var elemClassName;\n while (element) {\n elemClassName = attr(element, 'class');\n if (elemClassName) {\n if (elemClassName.indexOf(className) !== -1) {\n return true;\n }\n if (elemClassName.indexOf('highcharts-container') !== -1) {\n return false;\n }\n }\n element = element.parentNode;\n }\n },\n\n onTrackerMouseOut: function(e) {\n var series = this.chart.hoverSeries,\n relatedTarget = e.relatedTarget || e.toElement;\n this.isDirectTouch = false;\n if (series && relatedTarget && !series.stickyTracking &&\n !this.inClass(relatedTarget, 'highcharts-tooltip') &&\n (!this.inClass(relatedTarget, 'highcharts-series-' + series.index) || // #2499, #4465\n !this.inClass(relatedTarget, 'highcharts-tracker') // #5553\n )\n ) {\n series.onMouseOut();\n }\n },\n\n onContainerClick: function(e) {\n var chart = this.chart,\n hoverPoint = chart.hoverPoint,\n plotLeft = chart.plotLeft,\n plotTop = chart.plotTop;\n\n e = this.normalize(e);\n\n if (!chart.cancelClick) {\n\n // On tracker click, fire the series and point events. #783, #1583\n if (hoverPoint && this.inClass(e.target, 'highcharts-tracker')) {\n\n // the series click event\n fireEvent(hoverPoint.series, 'click', extend(e, {\n point: hoverPoint\n }));\n\n // the point click event\n if (chart.hoverPoint) { // it may be destroyed (#1844)\n hoverPoint.firePointEvent('click', e);\n }\n\n // When clicking outside a tracker, fire a chart event\n } else {\n extend(e, this.getCoordinates(e));\n\n // fire a click event in the chart\n if (chart.isInsidePlot(e.chartX - plotLeft, e.chartY - plotTop)) {\n fireEvent(chart, 'click', e);\n }\n }\n\n\n }\n },\n\n /**\n * Set the JS DOM events on the container and document. This method should contain\n * a one-to-one assignment between methods and their handlers. Any advanced logic should\n * be moved to the handler reflecting the event's name.\n */\n setDOMEvents: function() {\n\n var pointer = this,\n container = pointer.chart.container;\n\n container.onmousedown = function(e) {\n pointer.onContainerMouseDown(e);\n };\n container.onmousemove = function(e) {\n pointer.onContainerMouseMove(e);\n };\n container.onclick = function(e) {\n pointer.onContainerClick(e);\n };\n addEvent(container, 'mouseleave', pointer.onContainerMouseLeave);\n if (H.chartCount === 1) {\n addEvent(doc, 'mouseup', pointer.onDocumentMouseUp);\n }\n if (H.hasTouch) {\n container.ontouchstart = function(e) {\n pointer.onContainerTouchStart(e);\n };\n container.ontouchmove = function(e) {\n pointer.onContainerTouchMove(e);\n };\n if (H.chartCount === 1) {\n addEvent(doc, 'touchend', pointer.onDocumentTouchEnd);\n }\n }\n\n },\n\n /**\n * Destroys the Pointer object and disconnects DOM events.\n */\n destroy: function() {\n var pointer = this;\n\n if (pointer.unDocMouseMove) {\n pointer.unDocMouseMove();\n }\n\n removeEvent(\n pointer.chart.container,\n 'mouseleave',\n pointer.onContainerMouseLeave\n );\n if (!H.chartCount) {\n removeEvent(doc, 'mouseup', pointer.onDocumentMouseUp);\n removeEvent(doc, 'touchend', pointer.onDocumentTouchEnd);\n }\n\n // memory and CPU leak\n clearInterval(pointer.tooltipTimeout);\n\n H.objectEach(pointer, function(val, prop) {\n pointer[prop] = null;\n });\n }\n };\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var charts = H.charts,\n each = H.each,\n extend = H.extend,\n map = H.map,\n noop = H.noop,\n pick = H.pick,\n Pointer = H.Pointer;\n\n /* Support for touch devices */\n extend(Pointer.prototype, /** @lends Pointer.prototype */ {\n\n /**\n * Run translation operations\n */\n pinchTranslate: function(pinchDown, touches, transform, selectionMarker, clip, lastValidTouch) {\n if (this.zoomHor) {\n this.pinchTranslateDirection(true, pinchDown, touches, transform, selectionMarker, clip, lastValidTouch);\n }\n if (this.zoomVert) {\n this.pinchTranslateDirection(false, pinchDown, touches, transform, selectionMarker, clip, lastValidTouch);\n }\n },\n\n /**\n * Run translation operations for each direction (horizontal and vertical) independently\n */\n pinchTranslateDirection: function(horiz, pinchDown, touches, transform,\n selectionMarker, clip, lastValidTouch, forcedScale) {\n var chart = this.chart,\n xy = horiz ? 'x' : 'y',\n XY = horiz ? 'X' : 'Y',\n sChartXY = 'chart' + XY,\n wh = horiz ? 'width' : 'height',\n plotLeftTop = chart['plot' + (horiz ? 'Left' : 'Top')],\n selectionWH,\n selectionXY,\n clipXY,\n scale = forcedScale || 1,\n inverted = chart.inverted,\n bounds = chart.bounds[horiz ? 'h' : 'v'],\n singleTouch = pinchDown.length === 1,\n touch0Start = pinchDown[0][sChartXY],\n touch0Now = touches[0][sChartXY],\n touch1Start = !singleTouch && pinchDown[1][sChartXY],\n touch1Now = !singleTouch && touches[1][sChartXY],\n outOfBounds,\n transformScale,\n scaleKey,\n setScale = function() {\n // Don't zoom if fingers are too close on this axis\n if (!singleTouch && Math.abs(touch0Start - touch1Start) > 20) {\n scale = forcedScale || Math.abs(touch0Now - touch1Now) / Math.abs(touch0Start - touch1Start);\n }\n\n clipXY = ((plotLeftTop - touch0Now) / scale) + touch0Start;\n selectionWH = chart['plot' + (horiz ? 'Width' : 'Height')] / scale;\n };\n\n // Set the scale, first pass\n setScale();\n\n selectionXY = clipXY; // the clip position (x or y) is altered if out of bounds, the selection position is not\n\n // Out of bounds\n if (selectionXY < bounds.min) {\n selectionXY = bounds.min;\n outOfBounds = true;\n } else if (selectionXY + selectionWH > bounds.max) {\n selectionXY = bounds.max - selectionWH;\n outOfBounds = true;\n }\n\n // Is the chart dragged off its bounds, determined by dataMin and dataMax?\n if (outOfBounds) {\n\n // Modify the touchNow position in order to create an elastic drag movement. This indicates\n // to the user that the chart is responsive but can't be dragged further.\n touch0Now -= 0.8 * (touch0Now - lastValidTouch[xy][0]);\n if (!singleTouch) {\n touch1Now -= 0.8 * (touch1Now - lastValidTouch[xy][1]);\n }\n\n // Set the scale, second pass to adapt to the modified touchNow positions\n setScale();\n\n } else {\n lastValidTouch[xy] = [touch0Now, touch1Now];\n }\n\n // Set geometry for clipping, selection and transformation\n if (!inverted) {\n clip[xy] = clipXY - plotLeftTop;\n clip[wh] = selectionWH;\n }\n scaleKey = inverted ? (horiz ? 'scaleY' : 'scaleX') : 'scale' + XY;\n transformScale = inverted ? 1 / scale : scale;\n\n selectionMarker[wh] = selectionWH;\n selectionMarker[xy] = selectionXY;\n transform[scaleKey] = scale;\n transform['translate' + XY] = (transformScale * plotLeftTop) + (touch0Now - (transformScale * touch0Start));\n },\n\n /**\n * Handle touch events with two touches\n */\n pinch: function(e) {\n\n var self = this,\n chart = self.chart,\n pinchDown = self.pinchDown,\n touches = e.touches,\n touchesLength = touches.length,\n lastValidTouch = self.lastValidTouch,\n hasZoom = self.hasZoom,\n selectionMarker = self.selectionMarker,\n transform = {},\n fireClickEvent = touchesLength === 1 && ((self.inClass(e.target, 'highcharts-tracker') &&\n chart.runTrackerClick) || self.runChartClick),\n clip = {};\n\n // Don't initiate panning until the user has pinched. This prevents us from\n // blocking page scrolling as users scroll down a long page (#4210).\n if (touchesLength > 1) {\n self.initiated = true;\n }\n\n // On touch devices, only proceed to trigger click if a handler is defined\n if (hasZoom && self.initiated && !fireClickEvent) {\n e.preventDefault();\n }\n\n // Normalize each touch\n map(touches, function(e) {\n return self.normalize(e);\n });\n\n // Register the touch start position\n if (e.type === 'touchstart') {\n each(touches, function(e, i) {\n pinchDown[i] = {\n chartX: e.chartX,\n chartY: e.chartY\n };\n });\n lastValidTouch.x = [pinchDown[0].chartX, pinchDown[1] && pinchDown[1].chartX];\n lastValidTouch.y = [pinchDown[0].chartY, pinchDown[1] && pinchDown[1].chartY];\n\n // Identify the data bounds in pixels\n each(chart.axes, function(axis) {\n if (axis.zoomEnabled) {\n var bounds = chart.bounds[axis.horiz ? 'h' : 'v'],\n minPixelPadding = axis.minPixelPadding,\n min = axis.toPixels(pick(axis.options.min, axis.dataMin)),\n max = axis.toPixels(pick(axis.options.max, axis.dataMax)),\n absMin = Math.min(min, max),\n absMax = Math.max(min, max);\n\n // Store the bounds for use in the touchmove handler\n bounds.min = Math.min(axis.pos, absMin - minPixelPadding);\n bounds.max = Math.max(axis.pos + axis.len, absMax + minPixelPadding);\n }\n });\n self.res = true; // reset on next move\n\n // Optionally move the tooltip on touchmove\n } else if (self.followTouchMove && touchesLength === 1) {\n this.runPointActions(self.normalize(e));\n\n // Event type is touchmove, handle panning and pinching\n } else if (pinchDown.length) { // can be 0 when releasing, if touchend fires first\n\n\n // Set the marker\n if (!selectionMarker) {\n self.selectionMarker = selectionMarker = extend({\n destroy: noop,\n touch: true\n }, chart.plotBox);\n }\n\n self.pinchTranslate(pinchDown, touches, transform, selectionMarker, clip, lastValidTouch);\n\n self.hasPinched = hasZoom;\n\n // Scale and translate the groups to provide visual feedback during pinching\n self.scaleGroups(transform, clip);\n\n if (self.res) {\n self.res = false;\n this.reset(false, 0);\n }\n }\n },\n\n /**\n * General touch handler shared by touchstart and touchmove.\n */\n touch: function(e, start) {\n var chart = this.chart,\n hasMoved,\n pinchDown,\n isInside;\n\n if (chart.index !== H.hoverChartIndex) {\n this.onContainerMouseLeave({\n relatedTarget: true\n });\n }\n H.hoverChartIndex = chart.index;\n\n if (e.touches.length === 1) {\n\n e = this.normalize(e);\n\n isInside = chart.isInsidePlot(\n e.chartX - chart.plotLeft,\n e.chartY - chart.plotTop\n );\n if (isInside && !chart.openMenu) {\n\n // Run mouse events and display tooltip etc\n if (start) {\n this.runPointActions(e);\n }\n\n // Android fires touchmove events after the touchstart even if the\n // finger hasn't moved, or moved only a pixel or two. In iOS however,\n // the touchmove doesn't fire unless the finger moves more than ~4px.\n // So we emulate this behaviour in Android by checking how much it\n // moved, and cancelling on small distances. #3450.\n if (e.type === 'touchmove') {\n pinchDown = this.pinchDown;\n hasMoved = pinchDown[0] ? Math.sqrt( // #5266\n Math.pow(pinchDown[0].chartX - e.chartX, 2) +\n Math.pow(pinchDown[0].chartY - e.chartY, 2)\n ) >= 4 : false;\n }\n\n if (pick(hasMoved, true)) {\n this.pinch(e);\n }\n\n } else if (start) {\n // Hide the tooltip on touching outside the plot area (#1203)\n this.reset();\n }\n\n } else if (e.touches.length === 2) {\n this.pinch(e);\n }\n },\n\n onContainerTouchStart: function(e) {\n this.zoomOption(e);\n this.touch(e, true);\n },\n\n onContainerTouchMove: function(e) {\n this.touch(e);\n },\n\n onDocumentTouchEnd: function(e) {\n if (charts[H.hoverChartIndex]) {\n charts[H.hoverChartIndex].pointer.drop(e);\n }\n }\n\n });\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var addEvent = H.addEvent,\n charts = H.charts,\n css = H.css,\n doc = H.doc,\n extend = H.extend,\n hasTouch = H.hasTouch,\n noop = H.noop,\n Pointer = H.Pointer,\n removeEvent = H.removeEvent,\n win = H.win,\n wrap = H.wrap;\n\n if (!hasTouch && (win.PointerEvent || win.MSPointerEvent)) {\n\n // The touches object keeps track of the points being touched at all times\n var touches = {},\n hasPointerEvent = !!win.PointerEvent,\n getWebkitTouches = function() {\n var fake = [];\n fake.item = function(i) {\n return this[i];\n };\n H.objectEach(touches, function(touch) {\n fake.push({\n pageX: touch.pageX,\n pageY: touch.pageY,\n target: touch.target\n });\n });\n return fake;\n },\n translateMSPointer = function(e, method, wktype, func) {\n var p;\n if ((e.pointerType === 'touch' || e.pointerType === e.MSPOINTER_TYPE_TOUCH) && charts[H.hoverChartIndex]) {\n func(e);\n p = charts[H.hoverChartIndex].pointer;\n p[method]({\n type: wktype,\n target: e.currentTarget,\n preventDefault: noop,\n touches: getWebkitTouches()\n });\n }\n };\n\n /**\n * Extend the Pointer prototype with methods for each event handler and more\n */\n extend(Pointer.prototype, /** @lends Pointer.prototype */ {\n onContainerPointerDown: function(e) {\n translateMSPointer(e, 'onContainerTouchStart', 'touchstart', function(e) {\n touches[e.pointerId] = {\n pageX: e.pageX,\n pageY: e.pageY,\n target: e.currentTarget\n };\n });\n },\n onContainerPointerMove: function(e) {\n translateMSPointer(e, 'onContainerTouchMove', 'touchmove', function(e) {\n touches[e.pointerId] = {\n pageX: e.pageX,\n pageY: e.pageY\n };\n if (!touches[e.pointerId].target) {\n touches[e.pointerId].target = e.currentTarget;\n }\n });\n },\n onDocumentPointerUp: function(e) {\n translateMSPointer(e, 'onDocumentTouchEnd', 'touchend', function(e) {\n delete touches[e.pointerId];\n });\n },\n\n /**\n * Add or remove the MS Pointer specific events\n */\n batchMSEvents: function(fn) {\n fn(this.chart.container, hasPointerEvent ? 'pointerdown' : 'MSPointerDown', this.onContainerPointerDown);\n fn(this.chart.container, hasPointerEvent ? 'pointermove' : 'MSPointerMove', this.onContainerPointerMove);\n fn(doc, hasPointerEvent ? 'pointerup' : 'MSPointerUp', this.onDocumentPointerUp);\n }\n });\n\n // Disable default IE actions for pinch and such on chart element\n wrap(Pointer.prototype, 'init', function(proceed, chart, options) {\n proceed.call(this, chart, options);\n if (this.hasZoom) { // #4014\n css(chart.container, {\n '-ms-touch-action': 'none',\n 'touch-action': 'none'\n });\n }\n });\n\n // Add IE specific touch events to chart\n wrap(Pointer.prototype, 'setDOMEvents', function(proceed) {\n proceed.apply(this);\n if (this.hasZoom || this.followTouchMove) {\n this.batchMSEvents(addEvent);\n }\n });\n // Destroy MS events also\n wrap(Pointer.prototype, 'destroy', function(proceed) {\n this.batchMSEvents(removeEvent);\n proceed.call(this);\n });\n }\n\n }(Highcharts));\n (function(Highcharts) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var H = Highcharts,\n\n addEvent = H.addEvent,\n css = H.css,\n discardElement = H.discardElement,\n defined = H.defined,\n each = H.each,\n isFirefox = H.isFirefox,\n marginNames = H.marginNames,\n merge = H.merge,\n pick = H.pick,\n setAnimation = H.setAnimation,\n stableSort = H.stableSort,\n win = H.win,\n wrap = H.wrap;\n\n /**\n * The overview of the chart's series. The legend object is instanciated\n * internally in the chart constructor, and available from `chart.legend`. Each\n * chart has only one legend.\n * \n * @class\n */\n Highcharts.Legend = function(chart, options) {\n this.init(chart, options);\n };\n\n Highcharts.Legend.prototype = {\n\n /**\n * Initialize the legend\n */\n init: function(chart, options) {\n\n this.chart = chart;\n\n this.setOptions(options);\n\n if (options.enabled) {\n\n // Render it\n this.render();\n\n // move checkboxes\n addEvent(this.chart, 'endResize', function() {\n this.legend.positionCheckboxes();\n });\n }\n },\n\n setOptions: function(options) {\n\n var padding = pick(options.padding, 8);\n\n this.options = options;\n\n\n this.itemStyle = options.itemStyle;\n this.itemHiddenStyle = merge(this.itemStyle, options.itemHiddenStyle);\n\n this.itemMarginTop = options.itemMarginTop || 0;\n this.padding = padding;\n this.initialItemY = padding - 5; // 5 is pixels above the text\n this.maxItemWidth = 0;\n this.itemHeight = 0;\n this.symbolWidth = pick(options.symbolWidth, 16);\n this.pages = [];\n\n },\n\n /**\n * Update the legend with new options. Equivalent to running `chart.update`\n * with a legend configuration option.\n * @param {LegendOptions} options\n * Legend options.\n * @param {Boolean} [redraw=true]\n * Whether to redraw the chart.\n *\n * @sample highcharts/legend/legend-update/\n * Legend update\n */\n update: function(options, redraw) {\n var chart = this.chart;\n\n this.setOptions(merge(true, this.options, options));\n this.destroy();\n chart.isDirtyLegend = chart.isDirtyBox = true;\n if (pick(redraw, true)) {\n chart.redraw();\n }\n },\n\n /**\n * Set the colors for the legend item\n * @param {Object} item A Series or Point instance\n * @param {Object} visible Dimmed or colored\n */\n colorizeItem: function(item, visible) {\n item.legendGroup[visible ? 'removeClass' : 'addClass'](\n 'highcharts-legend-item-hidden'\n );\n\n\n var legend = this,\n options = legend.options,\n legendItem = item.legendItem,\n legendLine = item.legendLine,\n legendSymbol = item.legendSymbol,\n hiddenColor = legend.itemHiddenStyle.color,\n textColor = visible ? options.itemStyle.color : hiddenColor,\n symbolColor = visible ? (item.color || hiddenColor) : hiddenColor,\n markerOptions = item.options && item.options.marker,\n symbolAttr = {\n fill: symbolColor\n };\n\n if (legendItem) {\n legendItem.css({\n fill: textColor,\n color: textColor // #1553, oldIE\n });\n }\n if (legendLine) {\n legendLine.attr({\n stroke: symbolColor\n });\n }\n\n if (legendSymbol) {\n\n // Apply marker options\n if (markerOptions && legendSymbol.isMarker) { // #585\n //symbolAttr.stroke = symbolColor;\n symbolAttr = item.pointAttribs();\n if (!visible) {\n H.objectEach(symbolAttr, function(val, key) {\n symbolAttr[key] = hiddenColor;\n });\n }\n }\n\n legendSymbol.attr(symbolAttr);\n }\n\n },\n\n /**\n * Position the legend item\n * @param {Object} item A Series or Point instance\n */\n positionItem: function(item) {\n var legend = this,\n options = legend.options,\n symbolPadding = options.symbolPadding,\n ltr = !options.rtl,\n legendItemPos = item._legendItemPos,\n itemX = legendItemPos[0],\n itemY = legendItemPos[1],\n checkbox = item.checkbox,\n legendGroup = item.legendGroup;\n\n if (legendGroup && legendGroup.element) {\n legendGroup.translate(\n ltr ?\n itemX :\n legend.legendWidth - itemX - 2 * symbolPadding - 4,\n itemY\n );\n }\n\n if (checkbox) {\n checkbox.x = itemX;\n checkbox.y = itemY;\n }\n },\n\n /**\n * Destroy a single legend item\n * @param {Object} item The series or point\n */\n destroyItem: function(item) {\n var checkbox = item.checkbox;\n\n // destroy SVG elements\n each(\n ['legendItem', 'legendLine', 'legendSymbol', 'legendGroup'],\n function(key) {\n if (item[key]) {\n item[key] = item[key].destroy();\n }\n }\n );\n\n if (checkbox) {\n discardElement(item.checkbox);\n }\n },\n\n /**\n * Destroys the legend.\n */\n destroy: function() {\n function destroyItems(key) {\n if (this[key]) {\n this[key] = this[key].destroy();\n }\n }\n\n // Destroy items\n each(this.getAllItems(), function(item) {\n each(['legendItem', 'legendGroup'], destroyItems, item);\n });\n\n // Destroy legend elements\n each([\n 'clipRect',\n 'up',\n 'down',\n 'pager',\n 'nav',\n 'box',\n 'title',\n 'group'\n ], destroyItems, this);\n this.display = null; // Reset in .render on update.\n },\n\n /**\n * Position the checkboxes after the width is determined\n */\n positionCheckboxes: function(scrollOffset) {\n var alignAttr = this.group && this.group.alignAttr,\n translateY,\n clipHeight = this.clipHeight || this.legendHeight,\n titleHeight = this.titleHeight;\n\n if (alignAttr) {\n translateY = alignAttr.translateY;\n each(this.allItems, function(item) {\n var checkbox = item.checkbox,\n top;\n\n if (checkbox) {\n top = translateY + titleHeight + checkbox.y +\n (scrollOffset || 0) + 3;\n css(checkbox, {\n left: (alignAttr.translateX + item.checkboxOffset +\n checkbox.x - 20) + 'px',\n top: top + 'px',\n display: top > translateY - 6 && top < translateY +\n clipHeight - 6 ? '' : 'none'\n });\n }\n });\n }\n },\n\n /**\n * Render the legend title on top of the legend\n */\n renderTitle: function() {\n var options = this.options,\n padding = this.padding,\n titleOptions = options.title,\n titleHeight = 0,\n bBox;\n\n if (titleOptions.text) {\n if (!this.title) {\n this.title = this.chart.renderer.label(\n titleOptions.text,\n padding - 3,\n padding - 4,\n null,\n null,\n null,\n options.useHTML,\n null,\n 'legend-title'\n )\n .attr({\n zIndex: 1\n })\n\n .css(titleOptions.style)\n\n .add(this.group);\n }\n bBox = this.title.getBBox();\n titleHeight = bBox.height;\n this.offsetWidth = bBox.width; // #1717\n this.contentGroup.attr({\n translateY: titleHeight\n });\n }\n this.titleHeight = titleHeight;\n },\n\n /**\n * Set the legend item text\n */\n setText: function(item) {\n var options = this.options;\n item.legendItem.attr({\n text: options.labelFormat ?\n H.format(options.labelFormat, item) : options.labelFormatter.call(item)\n });\n },\n\n /**\n * Render a single specific legend item\n * @param {Object} item A series or point\n */\n renderItem: function(item) {\n var legend = this,\n chart = legend.chart,\n renderer = chart.renderer,\n options = legend.options,\n horizontal = options.layout === 'horizontal',\n symbolWidth = legend.symbolWidth,\n symbolPadding = options.symbolPadding,\n\n itemStyle = legend.itemStyle,\n itemHiddenStyle = legend.itemHiddenStyle,\n\n padding = legend.padding,\n itemDistance = horizontal ? pick(options.itemDistance, 20) : 0,\n ltr = !options.rtl,\n itemHeight,\n widthOption = options.width,\n itemMarginBottom = options.itemMarginBottom || 0,\n itemMarginTop = legend.itemMarginTop,\n bBox,\n itemWidth,\n li = item.legendItem,\n isSeries = !item.series,\n series = !isSeries && item.series.drawLegendSymbol ?\n item.series :\n item,\n seriesOptions = series.options,\n showCheckbox = legend.createCheckboxForItem &&\n seriesOptions &&\n seriesOptions.showCheckbox,\n // full width minus text width\n itemExtraWidth = symbolWidth + symbolPadding + itemDistance +\n (showCheckbox ? 20 : 0),\n useHTML = options.useHTML,\n fontSize = 12,\n itemClassName = item.options.className;\n\n if (!li) { // generate it once, later move it\n\n // Generate the group box, a group to hold the symbol and text. Text\n // is to be appended in Legend class.\n item.legendGroup = renderer.g('legend-item')\n .addClass(\n 'highcharts-' + series.type + '-series ' +\n 'highcharts-color-' + item.colorIndex +\n (itemClassName ? ' ' + itemClassName : '') +\n (isSeries ? ' highcharts-series-' + item.index : '')\n )\n .attr({\n zIndex: 1\n })\n .add(legend.scrollGroup);\n\n // Generate the list item text and add it to the group\n item.legendItem = li = renderer.text(\n '',\n ltr ? symbolWidth + symbolPadding : -symbolPadding,\n legend.baseline || 0,\n useHTML\n )\n\n // merge to prevent modifying original (#1021)\n .css(merge(item.visible ? itemStyle : itemHiddenStyle))\n\n .attr({\n align: ltr ? 'left' : 'right',\n zIndex: 2\n })\n .add(item.legendGroup);\n\n // Get the baseline for the first item - the font size is equal for\n // all\n if (!legend.baseline) {\n\n fontSize = itemStyle.fontSize;\n\n legend.fontMetrics = renderer.fontMetrics(\n fontSize,\n li\n );\n legend.baseline = legend.fontMetrics.f + 3 + itemMarginTop;\n li.attr('y', legend.baseline);\n }\n\n // Draw the legend symbol inside the group box\n legend.symbolHeight = options.symbolHeight || legend.fontMetrics.f;\n series.drawLegendSymbol(legend, item);\n\n if (legend.setItemEvents) {\n legend.setItemEvents(item, li, useHTML);\n }\n\n // add the HTML checkbox on top\n if (showCheckbox) {\n legend.createCheckboxForItem(item);\n }\n }\n\n // Colorize the items\n legend.colorizeItem(item, item.visible);\n\n // Take care of max width and text overflow (#6659)\n\n if (!itemStyle.width) {\n\n li.css({\n width: (options.itemWidth || chart.spacingBox.width) -\n itemExtraWidth\n });\n\n }\n\n\n // Always update the text\n legend.setText(item);\n\n // calculate the positions for the next line\n bBox = li.getBBox();\n\n itemWidth = item.checkboxOffset =\n options.itemWidth ||\n item.legendItemWidth ||\n bBox.width + itemExtraWidth;\n legend.itemHeight = itemHeight = Math.round(\n item.legendItemHeight || bBox.height || legend.symbolHeight\n );\n\n // If the item exceeds the width, start a new line\n if (\n horizontal &&\n legend.itemX - padding + itemWidth > (\n widthOption || (\n chart.spacingBox.width - 2 * padding - options.x\n )\n )\n ) {\n legend.itemX = padding;\n legend.itemY += itemMarginTop + legend.lastLineHeight +\n itemMarginBottom;\n legend.lastLineHeight = 0; // reset for next line (#915, #3976)\n }\n\n // If the item exceeds the height, start a new column\n /*if (!horizontal && legend.itemY + options.y +\n itemHeight > chart.chartHeight - spacingTop - spacingBottom) {\n legend.itemY = legend.initialItemY;\n legend.itemX += legend.maxItemWidth;\n legend.maxItemWidth = 0;\n }*/\n\n // Set the edge positions\n legend.maxItemWidth = Math.max(legend.maxItemWidth, itemWidth);\n legend.lastItemY = itemMarginTop + legend.itemY + itemMarginBottom;\n legend.lastLineHeight = Math.max( // #915\n itemHeight,\n legend.lastLineHeight\n );\n\n // cache the position of the newly generated or reordered items\n item._legendItemPos = [legend.itemX, legend.itemY];\n\n // advance\n if (horizontal) {\n legend.itemX += itemWidth;\n\n } else {\n legend.itemY += itemMarginTop + itemHeight + itemMarginBottom;\n legend.lastLineHeight = itemHeight;\n }\n\n // the width of the widest item\n legend.offsetWidth = widthOption || Math.max(\n (horizontal ? legend.itemX - padding - itemDistance : itemWidth) +\n padding,\n legend.offsetWidth\n );\n },\n\n /**\n * Get all items, which is one item per series for normal series and one\n * item per point for pie series.\n */\n getAllItems: function() {\n var allItems = [];\n each(this.chart.series, function(series) {\n var seriesOptions = series && series.options;\n\n // Handle showInLegend. If the series is linked to another series,\n // defaults to false.\n if (series && pick(\n seriesOptions.showInLegend, !defined(seriesOptions.linkedTo) ? undefined : false, true\n )) {\n\n // Use points or series for the legend item depending on\n // legendType\n allItems = allItems.concat(\n series.legendItems ||\n (\n seriesOptions.legendType === 'point' ?\n series.data :\n series\n )\n );\n }\n });\n return allItems;\n },\n\n /**\n * Adjust the chart margins by reserving space for the legend on only one\n * side of the chart. If the position is set to a corner, top or bottom is\n * reserved for horizontal legends and left or right for vertical ones.\n */\n adjustMargins: function(margin, spacing) {\n var chart = this.chart,\n options = this.options,\n // Use the first letter of each alignment option in order to detect\n // the side. (#4189 - use charAt(x) notation instead of [x] for IE7)\n alignment = options.align.charAt(0) +\n options.verticalAlign.charAt(0) +\n options.layout.charAt(0);\n\n if (!options.floating) {\n\n each([\n /(lth|ct|rth)/,\n /(rtv|rm|rbv)/,\n /(rbh|cb|lbh)/,\n /(lbv|lm|ltv)/\n ], function(alignments, side) {\n if (alignments.test(alignment) && !defined(margin[side])) {\n // Now we have detected on which side of the chart we should\n // reserve space for the legend\n chart[marginNames[side]] = Math.max(\n chart[marginNames[side]],\n (\n chart.legend[\n (side + 1) % 2 ? 'legendHeight' : 'legendWidth'\n ] + [1, -1, -1, 1][side] * options[\n (side % 2) ? 'x' : 'y'\n ] +\n pick(options.margin, 12) +\n spacing[side]\n )\n );\n }\n });\n }\n },\n\n /**\n * Render the legend. This method can be called both before and after\n * chart.render. If called after, it will only rearrange items instead\n * of creating new ones.\n */\n render: function() {\n var legend = this,\n chart = legend.chart,\n renderer = chart.renderer,\n legendGroup = legend.group,\n allItems,\n display,\n legendWidth,\n legendHeight,\n box = legend.box,\n options = legend.options,\n padding = legend.padding;\n\n legend.itemX = padding;\n legend.itemY = legend.initialItemY;\n legend.offsetWidth = 0;\n legend.lastItemY = 0;\n\n if (!legendGroup) {\n legend.group = legendGroup = renderer.g('legend')\n .attr({\n zIndex: 7\n })\n .add();\n legend.contentGroup = renderer.g()\n .attr({\n zIndex: 1\n }) // above background\n .add(legendGroup);\n legend.scrollGroup = renderer.g()\n .add(legend.contentGroup);\n }\n\n legend.renderTitle();\n\n // add each series or point\n allItems = legend.getAllItems();\n\n // sort by legendIndex\n stableSort(allItems, function(a, b) {\n return ((a.options && a.options.legendIndex) || 0) -\n ((b.options && b.options.legendIndex) || 0);\n });\n\n // reversed legend\n if (options.reversed) {\n allItems.reverse();\n }\n\n legend.allItems = allItems;\n legend.display = display = !!allItems.length;\n\n // render the items\n legend.lastLineHeight = 0;\n each(allItems, function(item) {\n legend.renderItem(item);\n });\n\n // Get the box\n legendWidth = (options.width || legend.offsetWidth) + padding;\n legendHeight = legend.lastItemY + legend.lastLineHeight +\n legend.titleHeight;\n legendHeight = legend.handleOverflow(legendHeight);\n legendHeight += padding;\n\n // Draw the border and/or background\n if (!box) {\n legend.box = box = renderer.rect()\n .addClass('highcharts-legend-box')\n .attr({\n r: options.borderRadius\n })\n .add(legendGroup);\n box.isNew = true;\n }\n\n\n // Presentational\n box\n .attr({\n stroke: options.borderColor,\n 'stroke-width': options.borderWidth || 0,\n fill: options.backgroundColor || 'none'\n })\n .shadow(options.shadow);\n\n\n if (legendWidth > 0 && legendHeight > 0) {\n box[box.isNew ? 'attr' : 'animate'](\n box.crisp({\n x: 0,\n y: 0,\n width: legendWidth,\n height: legendHeight\n }, box.strokeWidth())\n );\n box.isNew = false;\n }\n\n // hide the border if no items\n box[display ? 'show' : 'hide']();\n\n\n\n legend.legendWidth = legendWidth;\n legend.legendHeight = legendHeight;\n\n // Now that the legend width and height are established, put the items\n // in the final position\n each(allItems, function(item) {\n legend.positionItem(item);\n });\n\n // 1.x compatibility: positioning based on style\n /*var props = ['left', 'right', 'top', 'bottom'],\n prop,\n i = 4;\n while (i--) {\n prop = props[i];\n if (options.style[prop] && options.style[prop] !== 'auto') {\n options[i < 2 ? 'align' : 'verticalAlign'] = prop;\n options[i < 2 ? 'x' : 'y'] = \n pInt(options.style[prop]) * (i % 2 ? -1 : 1);\n }\n }*/\n\n if (display) {\n legendGroup.align(merge(options, {\n width: legendWidth,\n height: legendHeight\n }), true, 'spacingBox');\n }\n\n if (!chart.isResizing) {\n this.positionCheckboxes();\n }\n },\n\n /**\n * Set up the overflow handling by adding navigation with up and down arrows\n * below the legend.\n */\n handleOverflow: function(legendHeight) {\n var legend = this,\n chart = this.chart,\n renderer = chart.renderer,\n options = this.options,\n optionsY = options.y,\n alignTop = options.verticalAlign === 'top',\n padding = this.padding,\n spaceHeight = chart.spacingBox.height +\n (alignTop ? -optionsY : optionsY) - padding,\n maxHeight = options.maxHeight,\n clipHeight,\n clipRect = this.clipRect,\n navOptions = options.navigation,\n animation = pick(navOptions.animation, true),\n arrowSize = navOptions.arrowSize || 12,\n nav = this.nav,\n pages = this.pages,\n lastY,\n allItems = this.allItems,\n clipToHeight = function(height) {\n if (typeof height === 'number') {\n clipRect.attr({\n height: height\n });\n } else if (clipRect) { // Reset (#5912)\n legend.clipRect = clipRect.destroy();\n legend.contentGroup.clip();\n }\n\n // useHTML\n if (legend.contentGroup.div) {\n legend.contentGroup.div.style.clip = height ?\n 'rect(' + padding + 'px,9999px,' +\n (padding + height) + 'px,0)' :\n 'auto';\n }\n };\n\n\n // Adjust the height\n if (\n options.layout === 'horizontal' &&\n options.verticalAlign !== 'middle' &&\n !options.floating\n ) {\n spaceHeight /= 2;\n }\n if (maxHeight) {\n spaceHeight = Math.min(spaceHeight, maxHeight);\n }\n\n // Reset the legend height and adjust the clipping rectangle\n pages.length = 0;\n if (legendHeight > spaceHeight && navOptions.enabled !== false) {\n\n this.clipHeight = clipHeight =\n Math.max(spaceHeight - 20 - this.titleHeight - padding, 0);\n this.currentPage = pick(this.currentPage, 1);\n this.fullHeight = legendHeight;\n\n // Fill pages with Y positions so that the top of each a legend item\n // defines the scroll top for each page (#2098)\n each(allItems, function(item, i) {\n var y = item._legendItemPos[1],\n h = Math.round(item.legendItem.getBBox().height),\n len = pages.length;\n\n if (!len || (y - pages[len - 1] > clipHeight &&\n (lastY || y) !== pages[len - 1])) {\n pages.push(lastY || y);\n len++;\n }\n\n if (i === allItems.length - 1 &&\n y + h - pages[len - 1] > clipHeight) {\n pages.push(y);\n }\n if (y !== lastY) {\n lastY = y;\n }\n });\n\n // Only apply clipping if needed. Clipping causes blurred legend in\n // PDF export (#1787)\n if (!clipRect) {\n clipRect = legend.clipRect =\n renderer.clipRect(0, padding, 9999, 0);\n legend.contentGroup.clip(clipRect);\n }\n\n clipToHeight(clipHeight);\n\n // Add navigation elements\n if (!nav) {\n this.nav = nav = renderer.g()\n .attr({\n zIndex: 1\n })\n .add(this.group);\n\n this.up = renderer\n .symbol(\n 'triangle',\n 0,\n 0,\n arrowSize,\n arrowSize\n )\n .on('click', function() {\n legend.scroll(-1, animation);\n })\n .add(nav);\n\n this.pager = renderer.text('', 15, 10)\n .addClass('highcharts-legend-navigation')\n\n .css(navOptions.style)\n\n .add(nav);\n\n this.down = renderer\n .symbol(\n 'triangle-down',\n 0,\n 0,\n arrowSize,\n arrowSize\n )\n .on('click', function() {\n legend.scroll(1, animation);\n })\n .add(nav);\n }\n\n // Set initial position\n legend.scroll(0);\n\n legendHeight = spaceHeight;\n\n // Reset\n } else if (nav) {\n clipToHeight();\n this.nav = nav.destroy(); // #6322\n this.scrollGroup.attr({\n translateY: 1\n });\n this.clipHeight = 0; // #1379\n }\n\n return legendHeight;\n },\n\n /**\n * Scroll the legend by a number of pages\n * @param {Object} scrollBy\n * @param {Object} animation\n */\n scroll: function(scrollBy, animation) {\n var pages = this.pages,\n pageCount = pages.length,\n currentPage = this.currentPage + scrollBy,\n clipHeight = this.clipHeight,\n navOptions = this.options.navigation,\n pager = this.pager,\n padding = this.padding,\n scrollOffset;\n\n // When resizing while looking at the last page\n if (currentPage > pageCount) {\n currentPage = pageCount;\n }\n\n if (currentPage > 0) {\n\n if (animation !== undefined) {\n setAnimation(animation, this.chart);\n }\n\n this.nav.attr({\n translateX: padding,\n translateY: clipHeight + this.padding + 7 + this.titleHeight,\n visibility: 'visible'\n });\n this.up.attr({\n 'class': currentPage === 1 ?\n 'highcharts-legend-nav-inactive' : 'highcharts-legend-nav-active'\n });\n pager.attr({\n text: currentPage + '/' + pageCount\n });\n this.down.attr({\n 'x': 18 + this.pager.getBBox().width, // adjust to text width\n 'class': currentPage === pageCount ?\n 'highcharts-legend-nav-inactive' : 'highcharts-legend-nav-active'\n });\n\n\n this.up\n .attr({\n fill: currentPage === 1 ?\n navOptions.inactiveColor : navOptions.activeColor\n })\n .css({\n cursor: currentPage === 1 ? 'default' : 'pointer'\n });\n this.down\n .attr({\n fill: currentPage === pageCount ?\n navOptions.inactiveColor : navOptions.activeColor\n })\n .css({\n cursor: currentPage === pageCount ? 'default' : 'pointer'\n });\n\n\n scrollOffset = -pages[currentPage - 1] + this.initialItemY;\n\n this.scrollGroup.animate({\n translateY: scrollOffset\n });\n\n this.currentPage = currentPage;\n this.positionCheckboxes(scrollOffset);\n }\n\n }\n\n };\n\n /*\n * LegendSymbolMixin\n */\n\n H.LegendSymbolMixin = {\n\n /**\n * Get the series' symbol in the legend\n *\n * @param {Object} legend The legend object\n * @param {Object} item The series (this) or point\n */\n drawRectangle: function(legend, item) {\n var options = legend.options,\n symbolHeight = legend.symbolHeight,\n square = options.squareSymbol,\n symbolWidth = square ? symbolHeight : legend.symbolWidth;\n\n item.legendSymbol = this.chart.renderer.rect(\n square ? (legend.symbolWidth - symbolHeight) / 2 : 0,\n legend.baseline - symbolHeight + 1, // #3988\n symbolWidth,\n symbolHeight,\n pick(legend.options.symbolRadius, symbolHeight / 2)\n )\n .addClass('highcharts-point')\n .attr({\n zIndex: 3\n }).add(item.legendGroup);\n\n },\n\n /**\n * Get the series' symbol in the legend. This method should be overridable\n * to create custom symbols through\n * Highcharts.seriesTypes[type].prototype.drawLegendSymbols.\n *\n * @param {Object} legend The legend object\n */\n drawLineMarker: function(legend) {\n\n var options = this.options,\n markerOptions = options.marker,\n radius,\n legendSymbol,\n symbolWidth = legend.symbolWidth,\n symbolHeight = legend.symbolHeight,\n generalRadius = symbolHeight / 2,\n renderer = this.chart.renderer,\n legendItemGroup = this.legendGroup,\n verticalCenter = legend.baseline -\n Math.round(legend.fontMetrics.b * 0.3),\n attr = {};\n\n // Draw the line\n\n attr = {\n 'stroke-width': options.lineWidth || 0\n };\n if (options.dashStyle) {\n attr.dashstyle = options.dashStyle;\n }\n\n\n this.legendLine = renderer.path([\n 'M',\n 0,\n verticalCenter,\n 'L',\n symbolWidth,\n verticalCenter\n ])\n .addClass('highcharts-graph')\n .attr(attr)\n .add(legendItemGroup);\n\n // Draw the marker\n if (markerOptions && markerOptions.enabled !== false) {\n\n // Do not allow the marker to be larger than the symbolHeight\n radius = Math.min(\n pick(markerOptions.radius, generalRadius),\n generalRadius\n );\n\n // Restrict symbol markers size\n if (this.symbol.indexOf('url') === 0) {\n markerOptions = merge(markerOptions, {\n width: symbolHeight,\n height: symbolHeight\n });\n radius = 0;\n }\n\n this.legendSymbol = legendSymbol = renderer.symbol(\n this.symbol,\n (symbolWidth / 2) - radius,\n verticalCenter - radius,\n 2 * radius,\n 2 * radius,\n markerOptions\n )\n .addClass('highcharts-point')\n .add(legendItemGroup);\n legendSymbol.isMarker = true;\n }\n }\n };\n\n // Workaround for #2030, horizontal legend items not displaying in IE11 Preview,\n // and for #2580, a similar drawing flaw in Firefox 26.\n // Explore if there's a general cause for this. The problem may be related\n // to nested group elements, as the legend item texts are within 4 group\n // elements.\n if (/Trident\\/7\\.0/.test(win.navigator.userAgent) || isFirefox) {\n wrap(Highcharts.Legend.prototype, 'positionItem', function(proceed, item) {\n var legend = this,\n // If chart destroyed in sync, this is undefined (#2030)\n runPositionItem = function() {\n if (item._legendItemPos) {\n proceed.call(legend, item);\n }\n };\n\n // Do it now, for export and to get checkbox placement\n runPositionItem();\n\n // Do it after to work around the core issue\n setTimeout(runPositionItem);\n });\n }\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var addEvent = H.addEvent,\n animate = H.animate,\n animObject = H.animObject,\n attr = H.attr,\n doc = H.doc,\n Axis = H.Axis, // @todo add as requirement\n createElement = H.createElement,\n defaultOptions = H.defaultOptions,\n discardElement = H.discardElement,\n charts = H.charts,\n css = H.css,\n defined = H.defined,\n each = H.each,\n extend = H.extend,\n find = H.find,\n fireEvent = H.fireEvent,\n getStyle = H.getStyle,\n grep = H.grep,\n isNumber = H.isNumber,\n isObject = H.isObject,\n isString = H.isString,\n Legend = H.Legend, // @todo add as requirement\n marginNames = H.marginNames,\n merge = H.merge,\n objectEach = H.objectEach,\n Pointer = H.Pointer, // @todo add as requirement\n pick = H.pick,\n pInt = H.pInt,\n removeEvent = H.removeEvent,\n seriesTypes = H.seriesTypes,\n splat = H.splat,\n svg = H.svg,\n syncTimeout = H.syncTimeout,\n win = H.win,\n Renderer = H.Renderer;\n /**\n * The Chart class. The recommended constructor is {@link Highcharts#chart}.\n * @class Highcharts.Chart\n * @param {String|HTMLDOMElement} renderTo\n * The DOM element to render to, or its id.\n * @param {Options} options\n * The chart options structure.\n * @param {Function} [callback]\n * Function to run when the chart has loaded and and all external images\n * are loaded. Defining a {@link\n * https://api.highcharts.com/highcharts/chart.events.load|chart.event.load}\n * handler is equivalent.\n *\n * @example\n * var chart = new Highcharts.Chart('container', {\n * title: {\n * text: 'My chart'\n * },\n * series: [{\n * data: [1, 3, 2, 4]\n * }]\n * })\n */\n var Chart = H.Chart = function() {\n this.getArgs.apply(this, arguments);\n };\n\n /**\n * Factory function for basic charts. \n *\n * @function #chart\n * @memberOf Highcharts\n * @param {String|HTMLDOMElement} renderTo - The DOM element to render to, or\n * its id.\n * @param {Options} options - The chart options structure.\n * @param {Function} [callback] - Function to run when the chart has loaded and\n * and all external images are loaded. Defining a {@link\n * https://api.highcharts.com/highcharts/chart.events.load|chart.event.load}\n * handler is equivalent.\n * @return {Highcharts.Chart} - Returns the Chart object.\n *\n * @example\n * // Render a chart in to div#container\n * var chart = Highcharts.chart('container', {\n * title: {\n * text: 'My chart'\n * },\n * series: [{\n * data: [1, 3, 2, 4]\n * }]\n * });\n */\n H.chart = function(a, b, c) {\n return new Chart(a, b, c);\n };\n\n extend(Chart.prototype, /** @lends Highcharts.Chart.prototype */ {\n\n /**\n * Hook for modules\n */\n callbacks: [],\n\n /**\n * Handle the arguments passed to the constructor\n * @returns {Array} Arguments without renderTo\n */\n getArgs: function() {\n var args = [].slice.call(arguments);\n\n // Remove the optional first argument, renderTo, and\n // set it on this.\n if (isString(args[0]) || args[0].nodeName) {\n this.renderTo = args.shift();\n }\n this.init(args[0], args[1]);\n },\n\n /**\n * Initialize the chart\n */\n init: function(userOptions, callback) {\n\n // Handle regular options\n var options,\n type,\n seriesOptions = userOptions.series, // skip merging data points to increase performance\n userPlotOptions = userOptions.plotOptions || {};\n\n userOptions.series = null;\n options = merge(defaultOptions, userOptions); // do the merge\n\n // Override (by copy of user options) or clear tooltip options\n // in chart.options.plotOptions (#6218)\n for (type in options.plotOptions) {\n options.plotOptions[type].tooltip = (\n userPlotOptions[type] &&\n merge(userPlotOptions[type].tooltip) // override by copy\n ) || undefined; // or clear\n }\n // User options have higher priority than default options (#6218).\n // In case of exporting: path is changed\n options.tooltip.userOptions = (userOptions.chart &&\n userOptions.chart.forExport && userOptions.tooltip.userOptions) ||\n userOptions.tooltip;\n\n options.series = userOptions.series = seriesOptions; // set back the series data\n this.userOptions = userOptions;\n\n var optionsChart = options.chart;\n\n var chartEvents = optionsChart.events;\n\n this.margin = [];\n this.spacing = [];\n\n //this.runChartClick = chartEvents && !!chartEvents.click;\n this.bounds = {\n h: {},\n v: {}\n }; // Pixel data bounds for touch zoom\n\n this.callback = callback;\n this.isResizing = 0;\n\n /**\n * The options structure for the chart. It contains members for the sub\n * elements like series, legend, tooltip etc.\n *\n * @memberof Highcharts.Chart\n * @name options\n * @type {Options}\n */\n this.options = options;\n /**\n * All the axes in the chart.\n *\n * @memberof Highcharts.Chart\n * @name axes\n * @see Highcharts.Chart.xAxis\n * @see Highcharts.Chart.yAxis\n * @type {Array.}\n */\n this.axes = [];\n\n /**\n * All the current series in the chart.\n *\n * @memberof Highcharts.Chart\n * @name series\n * @type {Array.}\n */\n this.series = [];\n\n /**\n * The chart title. The title has an `update` method that allows\n * modifying the options directly or indirectly via `chart.update`.\n *\n * @memberof Highcharts.Chart\n * @name title\n * @type Object\n *\n * @sample highcharts/members/title-update/\n * Updating titles\n */\n\n /**\n * The chart subtitle. The subtitle has an `update` method that allows\n * modifying the options directly or indirectly via `chart.update`.\n *\n * @memberof Highcharts.Chart\n * @name subtitle\n * @type Object\n */\n\n\n\n this.hasCartesianSeries = optionsChart.showAxes;\n //this.axisOffset = undefined;\n //this.inverted = undefined;\n //this.loadingShown = undefined;\n //this.container = undefined;\n //this.chartWidth = undefined;\n //this.chartHeight = undefined;\n //this.marginRight = undefined;\n //this.marginBottom = undefined;\n //this.containerWidth = undefined;\n //this.containerHeight = undefined;\n //this.oldChartWidth = undefined;\n //this.oldChartHeight = undefined;\n\n //this.renderTo = undefined;\n\n //this.spacingBox = undefined\n\n //this.legend = undefined;\n\n // Elements\n //this.chartBackground = undefined;\n //this.plotBackground = undefined;\n //this.plotBGImage = undefined;\n //this.plotBorder = undefined;\n //this.loadingDiv = undefined;\n //this.loadingSpan = undefined;\n\n var chart = this;\n\n // Add the chart to the global lookup\n chart.index = charts.length;\n\n charts.push(chart);\n H.chartCount++;\n\n // Chart event handlers\n if (chartEvents) {\n objectEach(chartEvents, function(event, eventType) {\n addEvent(chart, eventType, event);\n });\n }\n\n /**\n * A collection of the X axes in the chart.\n * @type {Array.}\n * @name xAxis\n * @memberOf Highcharts.Chart\n */\n chart.xAxis = [];\n /**\n * A collection of the Y axes in the chart.\n * @type {Array.}\n * @name yAxis\n * @memberOf Highcharts.Chart\n */\n chart.yAxis = [];\n\n chart.pointCount = chart.colorCounter = chart.symbolCounter = 0;\n\n chart.firstRender();\n },\n\n /**\n * Initialize an individual series, called internally before render time\n */\n initSeries: function(options) {\n var chart = this,\n optionsChart = chart.options.chart,\n type = options.type || optionsChart.type || optionsChart.defaultSeriesType,\n series,\n Constr = seriesTypes[type];\n\n // No such series type\n if (!Constr) {\n H.error(17, true);\n }\n\n series = new Constr();\n series.init(this, options);\n return series;\n },\n\n /**\n * Order all series above a given index. When series are added and ordered\n * by configuration, only the last series is handled (#248, #1123, #2456,\n * #6112). This function is called on series initialization and destroy.\n *\n * @param {number} fromIndex - If this is given, only the series above this\n * index are handled.\n */\n orderSeries: function(fromIndex) {\n var series = this.series,\n i = fromIndex || 0;\n for (; i < series.length; i++) {\n if (series[i]) {\n series[i].index = i;\n series[i].name = series[i].name ||\n 'Series ' + (series[i].index + 1);\n }\n }\n },\n\n /**\n * Check whether a given point is within the plot area\n *\n * @param {Number} plotX Pixel x relative to the plot area\n * @param {Number} plotY Pixel y relative to the plot area\n * @param {Boolean} inverted Whether the chart is inverted\n */\n isInsidePlot: function(plotX, plotY, inverted) {\n var x = inverted ? plotY : plotX,\n y = inverted ? plotX : plotY;\n\n return x >= 0 &&\n x <= this.plotWidth &&\n y >= 0 &&\n y <= this.plotHeight;\n },\n\n /**\n * Redraw the chart after changes have been done to the data, axis extremes\n * chart size or chart elements. All methods for updating axes, series or\n * points have a parameter for redrawing the chart. This is `true` by\n * default. But in many cases you want to do more than one operation on the\n * chart before redrawing, for example add a number of points. In those\n * cases it is a waste of resources to redraw the chart for each new point\n * added. So you add the points and call `chart.redraw()` after.\n *\n * @param {AnimationOptions} animation\n * If or how to apply animation to the redraw.\n */\n redraw: function(animation) {\n var chart = this,\n axes = chart.axes,\n series = chart.series,\n pointer = chart.pointer,\n legend = chart.legend,\n redrawLegend = chart.isDirtyLegend,\n hasStackedSeries,\n hasDirtyStacks,\n hasCartesianSeries = chart.hasCartesianSeries,\n isDirtyBox = chart.isDirtyBox,\n i,\n serie,\n renderer = chart.renderer,\n isHiddenChart = renderer.isHidden(),\n afterRedraw = [];\n\n // Handle responsive rules, not only on resize (#6130)\n if (chart.setResponsive) {\n chart.setResponsive(false);\n }\n\n H.setAnimation(animation, chart);\n\n if (isHiddenChart) {\n chart.temporaryDisplay();\n }\n\n // Adjust title layout (reflow multiline text)\n chart.layOutTitles();\n\n // link stacked series\n i = series.length;\n while (i--) {\n serie = series[i];\n\n if (serie.options.stacking) {\n hasStackedSeries = true;\n\n if (serie.isDirty) {\n hasDirtyStacks = true;\n break;\n }\n }\n }\n if (hasDirtyStacks) { // mark others as dirty\n i = series.length;\n while (i--) {\n serie = series[i];\n if (serie.options.stacking) {\n serie.isDirty = true;\n }\n }\n }\n\n // Handle updated data in the series\n each(series, function(serie) {\n if (serie.isDirty) {\n if (serie.options.legendType === 'point') {\n if (serie.updateTotals) {\n serie.updateTotals();\n }\n redrawLegend = true;\n }\n }\n if (serie.isDirtyData) {\n fireEvent(serie, 'updatedData');\n }\n });\n\n // handle added or removed series\n if (redrawLegend && legend.options.enabled) { // series or pie points are added or removed\n // draw legend graphics\n legend.render();\n\n chart.isDirtyLegend = false;\n }\n\n // reset stacks\n if (hasStackedSeries) {\n chart.getStacks();\n }\n\n\n if (hasCartesianSeries) {\n // set axes scales\n each(axes, function(axis) {\n axis.updateNames();\n axis.setScale();\n });\n }\n\n chart.getMargins(); // #3098\n\n if (hasCartesianSeries) {\n // If one axis is dirty, all axes must be redrawn (#792, #2169)\n each(axes, function(axis) {\n if (axis.isDirty) {\n isDirtyBox = true;\n }\n });\n\n // redraw axes\n each(axes, function(axis) {\n\n // Fire 'afterSetExtremes' only if extremes are set\n var key = axis.min + ',' + axis.max;\n if (axis.extKey !== key) { // #821, #4452\n axis.extKey = key;\n afterRedraw.push(function() { // prevent a recursive call to chart.redraw() (#1119)\n fireEvent(axis, 'afterSetExtremes', extend(axis.eventArgs, axis.getExtremes())); // #747, #751\n delete axis.eventArgs;\n });\n }\n if (isDirtyBox || hasStackedSeries) {\n axis.redraw();\n }\n });\n }\n\n // the plot areas size has changed\n if (isDirtyBox) {\n chart.drawChartBox();\n }\n\n // Fire an event before redrawing series, used by the boost module to\n // clear previous series renderings.\n fireEvent(chart, 'predraw');\n\n // redraw affected series\n each(series, function(serie) {\n if ((isDirtyBox || serie.isDirty) && serie.visible) {\n serie.redraw();\n }\n // Set it here, otherwise we will have unlimited 'updatedData' calls\n // for a hidden series after setData(). Fixes #6012\n serie.isDirtyData = false;\n });\n\n // move tooltip or reset\n if (pointer) {\n pointer.reset(true);\n }\n\n // redraw if canvas\n renderer.draw();\n\n // Fire the events\n fireEvent(chart, 'redraw');\n fireEvent(chart, 'render');\n\n if (isHiddenChart) {\n chart.temporaryDisplay(true);\n }\n\n // Fire callbacks that are put on hold until after the redraw\n each(afterRedraw, function(callback) {\n callback.call();\n });\n },\n\n /**\n * Get an axis, series or point object by `id` as given in the configuration\n * options. Returns `undefined` if no item is found.\n * @param id {String} The id as given in the configuration options.\n * @return {Highcharts.Axis|Highcharts.Series|Highcharts.Point|undefined}\n * The retrieved item.\n * @sample highcharts/plotoptions/series-id/\n * Get series by id\n */\n get: function(id) {\n\n var ret,\n series = this.series,\n i;\n\n function itemById(item) {\n return item.id === id || (item.options && item.options.id === id);\n }\n\n ret =\n // Search axes\n find(this.axes, itemById) ||\n\n // Search series\n find(this.series, itemById);\n\n // Search points\n for (i = 0; !ret && i < series.length; i++) {\n ret = find(series[i].points || [], itemById);\n }\n\n return ret;\n },\n\n /**\n * Create the Axis instances based on the config options\n */\n getAxes: function() {\n var chart = this,\n options = this.options,\n xAxisOptions = options.xAxis = splat(options.xAxis || {}),\n yAxisOptions = options.yAxis = splat(options.yAxis || {}),\n optionsArray;\n\n // make sure the options are arrays and add some members\n each(xAxisOptions, function(axis, i) {\n axis.index = i;\n axis.isX = true;\n });\n\n each(yAxisOptions, function(axis, i) {\n axis.index = i;\n });\n\n // concatenate all axis options into one array\n optionsArray = xAxisOptions.concat(yAxisOptions);\n\n each(optionsArray, function(axisOptions) {\n new Axis(chart, axisOptions); // eslint-disable-line no-new\n });\n },\n\n\n /**\n * Returns an array of all currently selected points in the chart. Points\n * can be selected by clicking or programmatically by the {@link\n * Highcharts.Point#select} function.\n *\n * @return {Array.}\n * The currently selected points.\n *\n * @sample highcharts/plotoptions/series-allowpointselect-line/\n * Get selected points\n */\n getSelectedPoints: function() {\n var points = [];\n each(this.series, function(serie) {\n // series.data - for points outside of viewed range (#6445)\n points = points.concat(grep(serie.data || [], function(point) {\n return point.selected;\n }));\n });\n return points;\n },\n\n /**\n * Returns an array of all currently selected series in the chart. Series\n * can be selected either programmatically by the {@link\n * Highcharts.Series#select} function or by checking the checkbox next to\n * the legend item if {@link\n * https://api.highcharts.com/highcharts/plotOptions.series.showCheckbox|\n * series.showCheckBox} is true.\n * \n * @return {Array.}\n * The currently selected series.\n *\n * @sample highcharts/members/chart-getselectedseries/\n * Get selected series\n */\n getSelectedSeries: function() {\n return grep(this.series, function(serie) {\n return serie.selected;\n });\n },\n\n /**\n * Set a new title or subtitle for the chart.\n *\n * @param titleOptions {TitleOptions}\n * New title options.\n * @param subtitleOptions {SubtitleOptions}\n * New subtitle options.\n * @param redraw {Boolean}\n * Whether to redraw the chart or wait for a later call to \n * `chart.redraw()`.\n *\n * @sample highcharts/members/chart-settitle/ Set title text and styles\n *\n */\n setTitle: function(titleOptions, subtitleOptions, redraw) {\n var chart = this,\n options = chart.options,\n chartTitleOptions,\n chartSubtitleOptions;\n\n chartTitleOptions = options.title = merge(\n\n // Default styles\n {\n style: {\n color: '#333333',\n fontSize: options.isStock ? '16px' : '18px' // #2944\n }\n },\n\n options.title,\n titleOptions\n );\n chartSubtitleOptions = options.subtitle = merge(\n\n // Default styles\n {\n style: {\n color: '#666666'\n }\n },\n\n options.subtitle,\n subtitleOptions\n );\n\n // add title and subtitle\n each([\n ['title', titleOptions, chartTitleOptions],\n ['subtitle', subtitleOptions, chartSubtitleOptions]\n ], function(arr, i) {\n var name = arr[0],\n title = chart[name],\n titleOptions = arr[1],\n chartTitleOptions = arr[2];\n\n if (title && titleOptions) {\n chart[name] = title = title.destroy(); // remove old\n }\n\n if (chartTitleOptions && chartTitleOptions.text && !title) {\n chart[name] = chart.renderer.text(\n chartTitleOptions.text,\n 0,\n 0,\n chartTitleOptions.useHTML\n )\n .attr({\n align: chartTitleOptions.align,\n 'class': 'highcharts-' + name,\n zIndex: chartTitleOptions.zIndex || 4\n })\n .add();\n\n // Update methods, shortcut to Chart.setTitle\n chart[name].update = function(o) {\n chart.setTitle(!i && o, i && o);\n };\n\n\n // Presentational\n chart[name].css(chartTitleOptions.style);\n\n\n }\n });\n chart.layOutTitles(redraw);\n },\n\n /**\n * Lay out the chart titles and cache the full offset height for use\n * in getMargins\n */\n layOutTitles: function(redraw) {\n var titleOffset = 0,\n requiresDirtyBox,\n renderer = this.renderer,\n spacingBox = this.spacingBox;\n\n // Lay out the title and the subtitle respectively\n each(['title', 'subtitle'], function(key) {\n var title = this[key],\n titleOptions = this.options[key],\n offset = key === 'title' ? -3 :\n // Floating subtitle (#6574)\n titleOptions.verticalAlign ? 0 : titleOffset + 2,\n titleSize;\n\n if (title) {\n\n titleSize = titleOptions.style.fontSize;\n\n titleSize = renderer.fontMetrics(titleSize, title).b;\n\n title\n .css({\n width: (titleOptions.width ||\n spacingBox.width + titleOptions.widthAdjust) + 'px'\n })\n .align(extend({\n y: offset + titleSize\n }, titleOptions), false, 'spacingBox');\n\n if (!titleOptions.floating && !titleOptions.verticalAlign) {\n titleOffset = Math.ceil(\n titleOffset +\n // Skip the cache for HTML (#3481)\n title.getBBox(titleOptions.useHTML).height\n );\n }\n }\n }, this);\n\n requiresDirtyBox = this.titleOffset !== titleOffset;\n this.titleOffset = titleOffset; // used in getMargins\n\n if (!this.isDirtyBox && requiresDirtyBox) {\n this.isDirtyBox = requiresDirtyBox;\n // Redraw if necessary (#2719, #2744)\n if (this.hasRendered && pick(redraw, true) && this.isDirtyBox) {\n this.redraw();\n }\n }\n },\n\n /**\n * Get chart width and height according to options and container size\n */\n getChartSize: function() {\n var chart = this,\n optionsChart = chart.options.chart,\n widthOption = optionsChart.width,\n heightOption = optionsChart.height,\n renderTo = chart.renderTo;\n\n // Get inner width and height\n if (!defined(widthOption)) {\n chart.containerWidth = getStyle(renderTo, 'width');\n }\n if (!defined(heightOption)) {\n chart.containerHeight = getStyle(renderTo, 'height');\n }\n\n chart.chartWidth = Math.max( // #1393\n 0,\n widthOption || chart.containerWidth || 600 // #1460\n );\n chart.chartHeight = Math.max(\n 0,\n H.relativeLength(\n heightOption,\n chart.chartWidth\n ) || chart.containerHeight || 400\n );\n },\n\n /**\n * If the renderTo element has no offsetWidth, most likely one or more of\n * its parents are hidden. Loop up the DOM tree to temporarily display the\n * parents, then save the original display properties, and when the true\n * size is retrieved, reset them. Used on first render and on redraws.\n *\n * @param {Boolean} revert - Revert to the saved original styles.\n */\n temporaryDisplay: function(revert) {\n var node = this.renderTo,\n tempStyle;\n if (!revert) {\n while (node && node.style) {\n if (getStyle(node, 'display', false) === 'none') {\n node.hcOrigStyle = {\n display: node.style.display,\n height: node.style.height,\n overflow: node.style.overflow\n };\n tempStyle = {\n display: 'block',\n overflow: 'hidden'\n };\n if (node !== this.renderTo) {\n tempStyle.height = 0;\n }\n\n H.css(node, tempStyle);\n if (node.style.setProperty) { // #2631\n node.style.setProperty('display', 'block', 'important');\n }\n }\n node = node.parentNode;\n }\n } else {\n while (node && node.style) {\n if (node.hcOrigStyle) {\n H.css(node, node.hcOrigStyle);\n delete node.hcOrigStyle;\n }\n node = node.parentNode;\n }\n }\n },\n\n /**\n * Setter for the chart class name\n */\n setClassName: function(className) {\n this.container.className = 'highcharts-container ' + (className || '');\n },\n\n /**\n * Get the containing element, determine the size and create the inner\n * container div to hold the chart\n */\n getContainer: function() {\n var chart = this,\n container,\n options = chart.options,\n optionsChart = options.chart,\n chartWidth,\n chartHeight,\n renderTo = chart.renderTo,\n indexAttrName = 'data-highcharts-chart',\n oldChartIndex,\n Ren,\n containerId = H.uniqueKey(),\n containerStyle,\n key;\n\n if (!renderTo) {\n chart.renderTo = renderTo = optionsChart.renderTo;\n }\n\n if (isString(renderTo)) {\n chart.renderTo = renderTo = doc.getElementById(renderTo);\n }\n\n // Display an error if the renderTo is wrong\n if (!renderTo) {\n H.error(13, true);\n }\n\n // If the container already holds a chart, destroy it. The check for\n // hasRendered is there because web pages that are saved to disk from\n // the browser, will preserve the data-highcharts-chart attribute and\n // the SVG contents, but not an interactive chart. So in this case,\n // charts[oldChartIndex] will point to the wrong chart if any (#2609).\n oldChartIndex = pInt(attr(renderTo, indexAttrName));\n if (\n isNumber(oldChartIndex) &&\n charts[oldChartIndex] &&\n charts[oldChartIndex].hasRendered\n ) {\n charts[oldChartIndex].destroy();\n }\n\n // Make a reference to the chart from the div\n attr(renderTo, indexAttrName, chart.index);\n\n // remove previous chart\n renderTo.innerHTML = '';\n\n // If the container doesn't have an offsetWidth, it has or is a child of\n // a node that has display:none. We need to temporarily move it out to a\n // visible state to determine the size, else the legend and tooltips\n // won't render properly. The skipClone option is used in sparklines as\n // a micro optimization, saving about 1-2 ms each chart.\n if (!optionsChart.skipClone && !renderTo.offsetWidth) {\n chart.temporaryDisplay();\n }\n\n // get the width and height\n chart.getChartSize();\n chartWidth = chart.chartWidth;\n chartHeight = chart.chartHeight;\n\n // Create the inner container\n\n containerStyle = extend({\n position: 'relative',\n overflow: 'hidden', // needed for context menu (avoid scrollbars)\n // and content overflow in IE\n width: chartWidth + 'px',\n height: chartHeight + 'px',\n textAlign: 'left',\n lineHeight: 'normal', // #427\n zIndex: 0, // #1072\n '-webkit-tap-highlight-color': 'rgba(0,0,0,0)'\n }, optionsChart.style);\n\n\n /**\n * The containing HTML element of the chart. The container is\n * dynamically inserted into the element given as the `renderTo`\n * parameterin the {@link Highcharts#chart} constructor.\n *\n * @memberOf Highcharts.Chart\n * @type {HTMLDOMElement}\n */\n container = createElement(\n 'div', {\n id: containerId\n },\n containerStyle,\n renderTo\n );\n chart.container = container;\n\n // cache the cursor (#1650)\n chart._cursor = container.style.cursor;\n\n // Initialize the renderer\n Ren = H[optionsChart.renderer] || Renderer;\n chart.renderer = new Ren(\n container,\n chartWidth,\n chartHeight,\n null,\n optionsChart.forExport,\n options.exporting && options.exporting.allowHTML\n );\n\n\n chart.setClassName(optionsChart.className);\n\n chart.renderer.setStyle(optionsChart.style);\n\n\n // Add a reference to the charts index\n chart.renderer.chartIndex = chart.index;\n },\n\n /**\n * Calculate margins by rendering axis labels in a preliminary position.\n * Title, subtitle and legend have already been rendered at this stage, but\n * will be moved into their final positions\n */\n getMargins: function(skipAxes) {\n var chart = this,\n spacing = chart.spacing,\n margin = chart.margin,\n titleOffset = chart.titleOffset;\n\n chart.resetMargins();\n\n // Adjust for title and subtitle\n if (titleOffset && !defined(margin[0])) {\n chart.plotTop = Math.max(\n chart.plotTop,\n titleOffset + chart.options.title.margin + spacing[0]\n );\n }\n\n // Adjust for legend\n if (chart.legend.display) {\n chart.legend.adjustMargins(margin, spacing);\n }\n\n // adjust for scroller\n if (chart.extraMargin) {\n chart[chart.extraMargin.type] =\n (chart[chart.extraMargin.type] || 0) + chart.extraMargin.value;\n }\n if (chart.extraTopMargin) {\n chart.plotTop += chart.extraTopMargin;\n }\n if (!skipAxes) {\n this.getAxisMargins();\n }\n },\n\n getAxisMargins: function() {\n\n var chart = this,\n // [top, right, bottom, left]\n axisOffset = chart.axisOffset = [0, 0, 0, 0],\n margin = chart.margin;\n\n // pre-render axes to get labels offset width\n if (chart.hasCartesianSeries) {\n each(chart.axes, function(axis) {\n if (axis.visible) {\n axis.getOffset();\n }\n });\n }\n\n // Add the axis offsets\n each(marginNames, function(m, side) {\n if (!defined(margin[side])) {\n chart[m] += axisOffset[side];\n }\n });\n\n chart.setChartSize();\n\n },\n\n /**\n * Reflows the chart to its container. By default, the chart reflows\n * automatically to its container following a `window.resize` event, as per\n * the {@link https://api.highcharts/highcharts/chart.reflow|chart.reflow}\n * option. However, there are no reliable events for div resize, so if the\n * container is resized without a window resize event, this must be called\n * explicitly.\n *\n * @param {Object} e\n * Event arguments. Used primarily when the function is called\n * internally as a response to window resize.\n *\n * @sample highcharts/members/chart-reflow/\n * Resize div and reflow\n * @sample highcharts/chart/events-container/\n * Pop up and reflow\n */\n reflow: function(e) {\n var chart = this,\n optionsChart = chart.options.chart,\n renderTo = chart.renderTo,\n hasUserWidth = defined(optionsChart.width),\n width = optionsChart.width || getStyle(renderTo, 'width'),\n height = optionsChart.height || getStyle(renderTo, 'height'),\n target = e ? e.target : win;\n\n // Width and height checks for display:none. Target is doc in IE8 and\n // Opera, win in Firefox, Chrome and IE9.\n if (!hasUserWidth &&\n !chart.isPrinting &&\n width &&\n height &&\n (target === win || target === doc)\n ) {\n if (\n width !== chart.containerWidth ||\n height !== chart.containerHeight\n ) {\n clearTimeout(chart.reflowTimeout);\n // When called from window.resize, e is set, else it's called\n // directly (#2224)\n chart.reflowTimeout = syncTimeout(function() {\n // Set size, it may have been destroyed in the meantime\n // (#1257)\n if (chart.container) {\n chart.setSize(undefined, undefined, false);\n }\n }, e ? 100 : 0);\n }\n chart.containerWidth = width;\n chart.containerHeight = height;\n }\n },\n\n /**\n * Add the event handlers necessary for auto resizing\n */\n initReflow: function() {\n var chart = this,\n unbind;\n\n unbind = addEvent(win, 'resize', function(e) {\n chart.reflow(e);\n });\n addEvent(chart, 'destroy', unbind);\n\n // The following will add listeners to re-fit the chart before and after\n // printing (#2284). However it only works in WebKit. Should have worked\n // in Firefox, but not supported in IE.\n /*\n if (win.matchMedia) {\n win.matchMedia('print').addListener(function reflow() {\n chart.reflow();\n });\n }\n */\n },\n\n /**\n * Resize the chart to a given width and height. In order to set the width\n * only, the height argument may be skipped. To set the height only, pass\n * `undefined for the width.\n * @param {Number|undefined|null} [width]\n * The new pixel width of the chart. Since v4.2.6, the argument can\n * be `undefined` in order to preserve the current value (when\n * setting height only), or `null` to adapt to the width of the\n * containing element.\n * @param {Number|undefined|null} [height]\n * The new pixel height of the chart. Since v4.2.6, the argument can\n * be `undefined` in order to preserve the current value, or `null`\n * in order to adapt to the height of the containing element.\n * @param {AnimationOptions} [animation=true]\n * Whether and how to apply animation.\n *\n * @sample highcharts/members/chart-setsize-button/\n * Test resizing from buttons\n * @sample highcharts/members/chart-setsize-jquery-resizable/\n * Add a jQuery UI resizable\n * @sample stock/members/chart-setsize/\n * Highstock with UI resizable\n */\n setSize: function(width, height, animation) {\n var chart = this,\n renderer = chart.renderer,\n globalAnimation;\n\n // Handle the isResizing counter\n chart.isResizing += 1;\n\n // set the animation for the current process\n H.setAnimation(animation, chart);\n\n chart.oldChartHeight = chart.chartHeight;\n chart.oldChartWidth = chart.chartWidth;\n if (width !== undefined) {\n chart.options.chart.width = width;\n }\n if (height !== undefined) {\n chart.options.chart.height = height;\n }\n chart.getChartSize();\n\n // Resize the container with the global animation applied if enabled\n // (#2503)\n\n globalAnimation = renderer.globalAnimation;\n (globalAnimation ? animate : css)(chart.container, {\n width: chart.chartWidth + 'px',\n height: chart.chartHeight + 'px'\n }, globalAnimation);\n\n\n chart.setChartSize(true);\n renderer.setSize(chart.chartWidth, chart.chartHeight, animation);\n\n // handle axes\n each(chart.axes, function(axis) {\n axis.isDirty = true;\n axis.setScale();\n });\n\n chart.isDirtyLegend = true; // force legend redraw\n chart.isDirtyBox = true; // force redraw of plot and chart border\n\n chart.layOutTitles(); // #2857\n chart.getMargins();\n\n chart.redraw(animation);\n\n\n chart.oldChartHeight = null;\n fireEvent(chart, 'resize');\n\n // Fire endResize and set isResizing back. If animation is disabled,\n // fire without delay\n syncTimeout(function() {\n if (chart) {\n fireEvent(chart, 'endResize', null, function() {\n chart.isResizing -= 1;\n });\n }\n }, animObject(globalAnimation).duration);\n },\n\n /**\n * Set the public chart properties. This is done before and after the\n * pre-render to determine margin sizes\n */\n setChartSize: function(skipAxes) {\n var chart = this,\n inverted = chart.inverted,\n renderer = chart.renderer,\n chartWidth = chart.chartWidth,\n chartHeight = chart.chartHeight,\n optionsChart = chart.options.chart,\n spacing = chart.spacing,\n clipOffset = chart.clipOffset,\n clipX,\n clipY,\n plotLeft,\n plotTop,\n plotWidth,\n plotHeight,\n plotBorderWidth;\n\n function clipOffsetSide(side) {\n var offset = clipOffset[side] || 0;\n return Math.max(plotBorderWidth || offset, offset) / 2;\n }\n\n chart.plotLeft = plotLeft = Math.round(chart.plotLeft);\n chart.plotTop = plotTop = Math.round(chart.plotTop);\n chart.plotWidth = plotWidth = Math.max(\n 0,\n Math.round(chartWidth - plotLeft - chart.marginRight)\n );\n chart.plotHeight = plotHeight = Math.max(\n 0,\n Math.round(chartHeight - plotTop - chart.marginBottom)\n );\n\n chart.plotSizeX = inverted ? plotHeight : plotWidth;\n chart.plotSizeY = inverted ? plotWidth : plotHeight;\n\n chart.plotBorderWidth = optionsChart.plotBorderWidth || 0;\n\n // Set boxes used for alignment\n chart.spacingBox = renderer.spacingBox = {\n x: spacing[3],\n y: spacing[0],\n width: chartWidth - spacing[3] - spacing[1],\n height: chartHeight - spacing[0] - spacing[2]\n };\n chart.plotBox = renderer.plotBox = {\n x: plotLeft,\n y: plotTop,\n width: plotWidth,\n height: plotHeight\n };\n\n plotBorderWidth = 2 * Math.floor(chart.plotBorderWidth / 2);\n clipX = Math.ceil(clipOffsetSide(3));\n clipY = Math.ceil(clipOffsetSide(0));\n chart.clipBox = {\n x: clipX,\n y: clipY,\n width: Math.floor(\n chart.plotSizeX -\n clipOffsetSide(1) -\n clipX\n ),\n height: Math.max(\n 0,\n Math.floor(\n chart.plotSizeY -\n clipOffsetSide(2) -\n clipY\n )\n )\n };\n\n if (!skipAxes) {\n each(chart.axes, function(axis) {\n axis.setAxisSize();\n axis.setAxisTranslation();\n });\n }\n },\n\n /**\n * Initial margins before auto size margins are applied\n */\n resetMargins: function() {\n var chart = this,\n chartOptions = chart.options.chart;\n\n // Create margin and spacing array\n each(['margin', 'spacing'], function splashArrays(target) {\n var value = chartOptions[target],\n values = isObject(value) ? value : [value, value, value, value];\n\n each(['Top', 'Right', 'Bottom', 'Left'], function(sideName, side) {\n chart[target][side] = pick(\n chartOptions[target + sideName],\n values[side]\n );\n });\n });\n\n // Set margin names like chart.plotTop, chart.plotLeft,\n // chart.marginRight, chart.marginBottom.\n each(marginNames, function(m, side) {\n chart[m] = pick(chart.margin[side], chart.spacing[side]);\n });\n chart.axisOffset = [0, 0, 0, 0]; // top, right, bottom, left\n chart.clipOffset = [];\n },\n\n /**\n * Draw the borders and backgrounds for chart and plot area\n */\n drawChartBox: function() {\n var chart = this,\n optionsChart = chart.options.chart,\n renderer = chart.renderer,\n chartWidth = chart.chartWidth,\n chartHeight = chart.chartHeight,\n chartBackground = chart.chartBackground,\n plotBackground = chart.plotBackground,\n plotBorder = chart.plotBorder,\n chartBorderWidth,\n\n plotBGImage = chart.plotBGImage,\n chartBackgroundColor = optionsChart.backgroundColor,\n plotBackgroundColor = optionsChart.plotBackgroundColor,\n plotBackgroundImage = optionsChart.plotBackgroundImage,\n\n mgn,\n bgAttr,\n plotLeft = chart.plotLeft,\n plotTop = chart.plotTop,\n plotWidth = chart.plotWidth,\n plotHeight = chart.plotHeight,\n plotBox = chart.plotBox,\n clipRect = chart.clipRect,\n clipBox = chart.clipBox,\n verb = 'animate';\n\n // Chart area\n if (!chartBackground) {\n chart.chartBackground = chartBackground = renderer.rect()\n .addClass('highcharts-background')\n .add();\n verb = 'attr';\n }\n\n\n // Presentational\n chartBorderWidth = optionsChart.borderWidth || 0;\n mgn = chartBorderWidth + (optionsChart.shadow ? 8 : 0);\n\n bgAttr = {\n fill: chartBackgroundColor || 'none'\n };\n\n if (chartBorderWidth || chartBackground['stroke-width']) { // #980\n bgAttr.stroke = optionsChart.borderColor;\n bgAttr['stroke-width'] = chartBorderWidth;\n }\n chartBackground\n .attr(bgAttr)\n .shadow(optionsChart.shadow);\n\n chartBackground[verb]({\n x: mgn / 2,\n y: mgn / 2,\n width: chartWidth - mgn - chartBorderWidth % 2,\n height: chartHeight - mgn - chartBorderWidth % 2,\n r: optionsChart.borderRadius\n });\n\n // Plot background\n verb = 'animate';\n if (!plotBackground) {\n verb = 'attr';\n chart.plotBackground = plotBackground = renderer.rect()\n .addClass('highcharts-plot-background')\n .add();\n }\n plotBackground[verb](plotBox);\n\n\n // Presentational attributes for the background\n plotBackground\n .attr({\n fill: plotBackgroundColor || 'none'\n })\n .shadow(optionsChart.plotShadow);\n\n // Create the background image\n if (plotBackgroundImage) {\n if (!plotBGImage) {\n chart.plotBGImage = renderer.image(\n plotBackgroundImage,\n plotLeft,\n plotTop,\n plotWidth,\n plotHeight\n ).add();\n } else {\n plotBGImage.animate(plotBox);\n }\n }\n\n\n // Plot clip\n if (!clipRect) {\n chart.clipRect = renderer.clipRect(clipBox);\n } else {\n clipRect.animate({\n width: clipBox.width,\n height: clipBox.height\n });\n }\n\n // Plot area border\n verb = 'animate';\n if (!plotBorder) {\n verb = 'attr';\n chart.plotBorder = plotBorder = renderer.rect()\n .addClass('highcharts-plot-border')\n .attr({\n zIndex: 1 // Above the grid\n })\n .add();\n }\n\n\n // Presentational\n plotBorder.attr({\n stroke: optionsChart.plotBorderColor,\n 'stroke-width': optionsChart.plotBorderWidth || 0,\n fill: 'none'\n });\n\n\n plotBorder[verb](plotBorder.crisp({\n x: plotLeft,\n y: plotTop,\n width: plotWidth,\n height: plotHeight\n }, -plotBorder.strokeWidth())); //#3282 plotBorder should be negative;\n\n // reset\n chart.isDirtyBox = false;\n },\n\n /**\n * Detect whether a certain chart property is needed based on inspecting its\n * options and series. This mainly applies to the chart.inverted property,\n * and in extensions to the chart.angular and chart.polar properties.\n */\n propFromSeries: function() {\n var chart = this,\n optionsChart = chart.options.chart,\n klass,\n seriesOptions = chart.options.series,\n i,\n value;\n\n\n each(['inverted', 'angular', 'polar'], function(key) {\n\n // The default series type's class\n klass = seriesTypes[optionsChart.type ||\n optionsChart.defaultSeriesType];\n\n // Get the value from available chart-wide properties\n value =\n optionsChart[key] || // It is set in the options\n (klass && klass.prototype[key]); // The default series class\n // requires it\n\n // 4. Check if any the chart's series require it\n i = seriesOptions && seriesOptions.length;\n while (!value && i--) {\n klass = seriesTypes[seriesOptions[i].type];\n if (klass && klass.prototype[key]) {\n value = true;\n }\n }\n\n // Set the chart property\n chart[key] = value;\n });\n\n },\n\n /**\n * Link two or more series together. This is done initially from\n * Chart.render, and after Chart.addSeries and Series.remove.\n */\n linkSeries: function() {\n var chart = this,\n chartSeries = chart.series;\n\n // Reset links\n each(chartSeries, function(series) {\n series.linkedSeries.length = 0;\n });\n\n // Apply new links\n each(chartSeries, function(series) {\n var linkedTo = series.options.linkedTo;\n if (isString(linkedTo)) {\n if (linkedTo === ':previous') {\n linkedTo = chart.series[series.index - 1];\n } else {\n linkedTo = chart.get(linkedTo);\n }\n // #3341 avoid mutual linking\n if (linkedTo && linkedTo.linkedParent !== series) {\n linkedTo.linkedSeries.push(series);\n series.linkedParent = linkedTo;\n series.visible = pick(\n series.options.visible,\n linkedTo.options.visible,\n series.visible\n ); // #3879\n }\n }\n });\n },\n\n /**\n * Render series for the chart\n */\n renderSeries: function() {\n each(this.series, function(serie) {\n serie.translate();\n serie.render();\n });\n },\n\n /**\n * Render labels for the chart\n */\n renderLabels: function() {\n var chart = this,\n labels = chart.options.labels;\n if (labels.items) {\n each(labels.items, function(label) {\n var style = extend(labels.style, label.style),\n x = pInt(style.left) + chart.plotLeft,\n y = pInt(style.top) + chart.plotTop + 12;\n\n // delete to prevent rewriting in IE\n delete style.left;\n delete style.top;\n\n chart.renderer.text(\n label.html,\n x,\n y\n )\n .attr({\n zIndex: 2\n })\n .css(style)\n .add();\n\n });\n }\n },\n\n /**\n * Render all graphics for the chart\n */\n render: function() {\n var chart = this,\n axes = chart.axes,\n renderer = chart.renderer,\n options = chart.options,\n tempWidth,\n tempHeight,\n redoHorizontal,\n redoVertical;\n\n // Title\n chart.setTitle();\n\n\n // Legend\n chart.legend = new Legend(chart, options.legend);\n\n // Get stacks\n if (chart.getStacks) {\n chart.getStacks();\n }\n\n // Get chart margins\n chart.getMargins(true);\n chart.setChartSize();\n\n // Record preliminary dimensions for later comparison\n tempWidth = chart.plotWidth;\n tempHeight = chart.plotHeight = chart.plotHeight - 21; // 21 is the most common correction for X axis labels\n\n // Get margins by pre-rendering axes\n each(axes, function(axis) {\n axis.setScale();\n });\n chart.getAxisMargins();\n\n // If the plot area size has changed significantly, calculate tick positions again\n redoHorizontal = tempWidth / chart.plotWidth > 1.1;\n redoVertical = tempHeight / chart.plotHeight > 1.05; // Height is more sensitive\n\n if (redoHorizontal || redoVertical) {\n\n each(axes, function(axis) {\n if ((axis.horiz && redoHorizontal) || (!axis.horiz && redoVertical)) {\n axis.setTickInterval(true); // update to reflect the new margins\n }\n });\n chart.getMargins(); // second pass to check for new labels\n }\n\n // Draw the borders and backgrounds\n chart.drawChartBox();\n\n\n // Axes\n if (chart.hasCartesianSeries) {\n each(axes, function(axis) {\n if (axis.visible) {\n axis.render();\n }\n });\n }\n\n // The series\n if (!chart.seriesGroup) {\n chart.seriesGroup = renderer.g('series-group')\n .attr({\n zIndex: 3\n })\n .add();\n }\n chart.renderSeries();\n\n // Labels\n chart.renderLabels();\n\n // Credits\n chart.addCredits();\n\n // Handle responsiveness\n if (chart.setResponsive) {\n chart.setResponsive();\n }\n\n // Set flag\n chart.hasRendered = true;\n\n },\n\n /**\n * Set a new credits label for the chart.\n *\n * @param {CreditOptions} options\n * A configuration object for the new credits.\n * @sample highcharts/credits/credits-update/ Add and update credits\n */\n addCredits: function(credits) {\n var chart = this;\n\n credits = merge(true, this.options.credits, credits);\n if (credits.enabled && !this.credits) {\n\n /**\n * The chart's credits label. The label has an `update` method that\n * allows setting new options as per the {@link\n * https://api.highcharts.com/highcharts/credits|\n * credits options set}.\n *\n * @memberof Highcharts.Chart\n * @name credits\n * @type {Highcharts.SVGElement}\n */\n this.credits = this.renderer.text(\n credits.text + (this.mapCredits || ''),\n 0,\n 0\n )\n .addClass('highcharts-credits')\n .on('click', function() {\n if (credits.href) {\n win.location.href = credits.href;\n }\n })\n .attr({\n align: credits.position.align,\n zIndex: 8\n })\n\n .css(credits.style)\n\n .add()\n .align(credits.position);\n\n // Dynamically update\n this.credits.update = function(options) {\n chart.credits = chart.credits.destroy();\n chart.addCredits(options);\n };\n }\n },\n\n /**\n * Remove the chart and purge memory. This method is called internally\n * before adding a second chart into the same container, as well as on\n * window unload to prevent leaks.\n *\n * @sample highcharts/members/chart-destroy/\n * Destroy the chart from a button\n * @sample stock/members/chart-destroy/\n * Destroy with Highstock\n */\n destroy: function() {\n var chart = this,\n axes = chart.axes,\n series = chart.series,\n container = chart.container,\n i,\n parentNode = container && container.parentNode;\n\n // fire the chart.destoy event\n fireEvent(chart, 'destroy');\n\n // Delete the chart from charts lookup array\n if (chart.renderer.forExport) {\n H.erase(charts, chart); // #6569\n } else {\n charts[chart.index] = undefined;\n }\n H.chartCount--;\n chart.renderTo.removeAttribute('data-highcharts-chart');\n\n // remove events\n removeEvent(chart);\n\n // ==== Destroy collections:\n // Destroy axes\n i = axes.length;\n while (i--) {\n axes[i] = axes[i].destroy();\n }\n\n // Destroy scroller & scroller series before destroying base series\n if (this.scroller && this.scroller.destroy) {\n this.scroller.destroy();\n }\n\n // Destroy each series\n i = series.length;\n while (i--) {\n series[i] = series[i].destroy();\n }\n\n // ==== Destroy chart properties:\n each([\n 'title', 'subtitle', 'chartBackground', 'plotBackground',\n 'plotBGImage', 'plotBorder', 'seriesGroup', 'clipRect', 'credits',\n 'pointer', 'rangeSelector', 'legend', 'resetZoomButton', 'tooltip',\n 'renderer'\n ], function(name) {\n var prop = chart[name];\n\n if (prop && prop.destroy) {\n chart[name] = prop.destroy();\n }\n });\n\n // remove container and all SVG\n if (container) { // can break in IE when destroyed before finished loading\n container.innerHTML = '';\n removeEvent(container);\n if (parentNode) {\n discardElement(container);\n }\n\n }\n\n // clean it all up\n objectEach(chart, function(val, key) {\n delete chart[key];\n });\n\n },\n\n\n /**\n * VML namespaces can't be added until after complete. Listening\n * for Perini's doScroll hack is not enough.\n */\n isReadyToRender: function() {\n var chart = this;\n\n // Note: win == win.top is required\n if ((!svg && (win == win.top && doc.readyState !== 'complete'))) { // eslint-disable-line eqeqeq\n doc.attachEvent('onreadystatechange', function() {\n doc.detachEvent('onreadystatechange', chart.firstRender);\n if (doc.readyState === 'complete') {\n chart.firstRender();\n }\n });\n return false;\n }\n return true;\n },\n\n /**\n * Prepare for first rendering after all data are loaded\n */\n firstRender: function() {\n var chart = this,\n options = chart.options;\n\n // Check whether the chart is ready to render\n if (!chart.isReadyToRender()) {\n return;\n }\n\n // Create the container\n chart.getContainer();\n\n // Run an early event after the container and renderer are established\n fireEvent(chart, 'init');\n\n\n chart.resetMargins();\n chart.setChartSize();\n\n // Set the common chart properties (mainly invert) from the given series\n chart.propFromSeries();\n\n // get axes\n chart.getAxes();\n\n // Initialize the series\n each(options.series || [], function(serieOptions) {\n chart.initSeries(serieOptions);\n });\n\n chart.linkSeries();\n\n // Run an event after axes and series are initialized, but before render. At this stage,\n // the series data is indexed and cached in the xData and yData arrays, so we can access\n // those before rendering. Used in Highstock.\n fireEvent(chart, 'beforeRender');\n\n // depends on inverted and on margins being set\n if (Pointer) {\n chart.pointer = new Pointer(chart, options);\n }\n\n chart.render();\n\n // Fire the load event if there are no external images\n if (!chart.renderer.imgCount && chart.onload) {\n chart.onload();\n }\n\n // If the chart was rendered outside the top container, put it back in (#3679)\n chart.temporaryDisplay(true);\n\n },\n\n /** \n * On chart load\n */\n onload: function() {\n\n // Run callbacks\n each([this.callback].concat(this.callbacks), function(fn) {\n if (fn && this.index !== undefined) { // Chart destroyed in its own callback (#3600)\n fn.apply(this, [this]);\n }\n }, this);\n\n fireEvent(this, 'load');\n fireEvent(this, 'render');\n\n\n // Set up auto resize, check for not destroyed (#6068)\n if (defined(this.index) && this.options.chart.reflow !== false) {\n this.initReflow();\n }\n\n // Don't run again\n this.onload = null;\n }\n\n }); // end Chart\n\n }(Highcharts));\n (function(Highcharts) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var Point,\n H = Highcharts,\n\n each = H.each,\n extend = H.extend,\n erase = H.erase,\n fireEvent = H.fireEvent,\n format = H.format,\n isArray = H.isArray,\n isNumber = H.isNumber,\n pick = H.pick,\n removeEvent = H.removeEvent;\n\n /**\n * The Point object. The point objects are generated from the `series.data` \n * configuration objects or raw numbers. They can be accessed from the\n * `Series.points` array. Other ways to instaniate points are through {@link\n * Highcharts.Series#addPoint} or {@link Highcharts.Series#setData}.\n *\n * @class\n */\n\n Highcharts.Point = Point = function() {};\n Highcharts.Point.prototype = {\n\n /**\n * Initialize the point. Called internally based on the series.data option.\n * @param {Object} series The series object containing this point.\n * @param {Object} options The data in either number, array or object\n * format.\n * @param {Number} x Optionally, the X value of the.\n * @returns {Object} The Point instance.\n */\n init: function(series, options, x) {\n\n var point = this,\n colors,\n colorCount = series.chart.options.chart.colorCount,\n colorIndex;\n\n /**\n * The series object associated with the point.\n *\n * @name series\n * @memberof Highcharts.Point\n * @type Highcharts.Series\n */\n point.series = series;\n\n\n /**\n * The point's current color.\n * @name color\n * @memberof Highcharts.Point\n * @type {Color}\n */\n point.color = series.color; // #3445\n\n point.applyOptions(options, x);\n\n if (series.options.colorByPoint) {\n\n colors = series.options.colors || series.chart.options.colors;\n point.color = point.color || colors[series.colorCounter];\n colorCount = colors.length;\n\n colorIndex = series.colorCounter;\n series.colorCounter++;\n // loop back to zero\n if (series.colorCounter === colorCount) {\n series.colorCounter = 0;\n }\n } else {\n colorIndex = series.colorIndex;\n }\n point.colorIndex = pick(point.colorIndex, colorIndex);\n\n series.chart.pointCount++;\n return point;\n },\n /**\n * Apply the options containing the x and y data and possible some extra\n * properties. Called on point init or from point.update.\n *\n * @param {Object} options The point options as defined in series.data.\n * @param {Number} x Optionally, the X value.\n * @returns {Object} The Point instance.\n */\n applyOptions: function(options, x) {\n var point = this,\n series = point.series,\n pointValKey = series.options.pointValKey || series.pointValKey;\n\n options = Point.prototype.optionsToObject.call(this, options);\n\n // copy options directly to point\n extend(point, options);\n point.options = point.options ? extend(point.options, options) : options;\n\n // Since options are copied into the Point instance, some accidental options must be shielded (#5681)\n if (options.group) {\n delete point.group;\n }\n\n // For higher dimension series types. For instance, for ranges, point.y is mapped to point.low.\n if (pointValKey) {\n point.y = point[pointValKey];\n }\n point.isNull = pick(\n point.isValid && !point.isValid(),\n point.x === null || !isNumber(point.y, true)\n ); // #3571, check for NaN\n\n // The point is initially selected by options (#5777)\n if (point.selected) {\n point.state = 'select';\n }\n\n // If no x is set by now, get auto incremented value. All points must have an\n // x value, however the y value can be null to create a gap in the series\n if ('name' in point && x === undefined && series.xAxis && series.xAxis.hasNames) {\n point.x = series.xAxis.nameToX(point);\n }\n if (point.x === undefined && series) {\n if (x === undefined) {\n point.x = series.autoIncrement(point);\n } else {\n point.x = x;\n }\n }\n\n return point;\n },\n\n /**\n * Transform number or array configs into objects\n */\n optionsToObject: function(options) {\n var ret = {},\n series = this.series,\n keys = series.options.keys,\n pointArrayMap = keys || series.pointArrayMap || ['y'],\n valueCount = pointArrayMap.length,\n firstItemType,\n i = 0,\n j = 0;\n\n if (isNumber(options) || options === null) {\n ret[pointArrayMap[0]] = options;\n\n } else if (isArray(options)) {\n // with leading x value\n if (!keys && options.length > valueCount) {\n firstItemType = typeof options[0];\n if (firstItemType === 'string') {\n ret.name = options[0];\n } else if (firstItemType === 'number') {\n ret.x = options[0];\n }\n i++;\n }\n while (j < valueCount) {\n if (!keys || options[i] !== undefined) { // Skip undefined positions for keys\n ret[pointArrayMap[j]] = options[i];\n }\n i++;\n j++;\n }\n } else if (typeof options === 'object') {\n ret = options;\n\n // This is the fastest way to detect if there are individual point dataLabels that need\n // to be considered in drawDataLabels. These can only occur in object configs.\n if (options.dataLabels) {\n series._hasPointLabels = true;\n }\n\n // Same approach as above for markers\n if (options.marker) {\n series._hasPointMarkers = true;\n }\n }\n return ret;\n },\n\n /**\n * Get the CSS class names for individual points\n * @returns {String} The class name\n */\n getClassName: function() {\n return 'highcharts-point' +\n (this.selected ? ' highcharts-point-select' : '') +\n (this.negative ? ' highcharts-negative' : '') +\n (this.isNull ? ' highcharts-null-point' : '') +\n (this.colorIndex !== undefined ? ' highcharts-color-' +\n this.colorIndex : '') +\n (this.options.className ? ' ' + this.options.className : '') +\n (this.zone && this.zone.className ? ' ' +\n this.zone.className.replace('highcharts-negative', '') : '');\n },\n\n /**\n * Return the zone that the point belongs to\n */\n getZone: function() {\n var series = this.series,\n zones = series.zones,\n zoneAxis = series.zoneAxis || 'y',\n i = 0,\n zone;\n\n zone = zones[i];\n while (this[zoneAxis] >= zone.value) {\n zone = zones[++i];\n }\n\n if (zone && zone.color && !this.options.color) {\n this.color = zone.color;\n }\n\n return zone;\n },\n\n /**\n * Destroy a point to clear memory. Its reference still stays in series.data.\n */\n destroy: function() {\n var point = this,\n series = point.series,\n chart = series.chart,\n hoverPoints = chart.hoverPoints,\n prop;\n\n chart.pointCount--;\n\n if (hoverPoints) {\n point.setState();\n erase(hoverPoints, point);\n if (!hoverPoints.length) {\n chart.hoverPoints = null;\n }\n\n }\n if (point === chart.hoverPoint) {\n point.onMouseOut();\n }\n\n // remove all events\n if (point.graphic || point.dataLabel) { // removeEvent and destroyElements are performance expensive\n removeEvent(point);\n point.destroyElements();\n }\n\n if (point.legendItem) { // pies have legend items\n chart.legend.destroyItem(point);\n }\n\n for (prop in point) {\n point[prop] = null;\n }\n\n\n },\n\n /**\n * Destroy SVG elements associated with the point\n */\n destroyElements: function() {\n var point = this,\n props = ['graphic', 'dataLabel', 'dataLabelUpper', 'connector', 'shadowGroup'],\n prop,\n i = 6;\n while (i--) {\n prop = props[i];\n if (point[prop]) {\n point[prop] = point[prop].destroy();\n }\n }\n },\n\n /**\n * Return the configuration hash needed for the data label and tooltip formatters\n */\n getLabelConfig: function() {\n return {\n x: this.category,\n y: this.y,\n color: this.color,\n colorIndex: this.colorIndex,\n key: this.name || this.category,\n series: this.series,\n point: this,\n percentage: this.percentage,\n total: this.total || this.stackTotal\n };\n },\n\n /**\n * Extendable method for formatting each point's tooltip line\n *\n * @return {String} A string to be concatenated in to the common tooltip text\n */\n tooltipFormatter: function(pointFormat) {\n\n // Insert options for valueDecimals, valuePrefix, and valueSuffix\n var series = this.series,\n seriesTooltipOptions = series.tooltipOptions,\n valueDecimals = pick(seriesTooltipOptions.valueDecimals, ''),\n valuePrefix = seriesTooltipOptions.valuePrefix || '',\n valueSuffix = seriesTooltipOptions.valueSuffix || '';\n\n // Loop over the point array map and replace unformatted values with sprintf formatting markup\n each(series.pointArrayMap || ['y'], function(key) {\n key = '{point.' + key; // without the closing bracket\n if (valuePrefix || valueSuffix) {\n pointFormat = pointFormat.replace(key + '}', valuePrefix + key + '}' + valueSuffix);\n }\n pointFormat = pointFormat.replace(key + '}', key + ':,.' + valueDecimals + 'f}');\n });\n\n return format(pointFormat, {\n point: this,\n series: this.series\n });\n },\n\n /**\n * Fire an event on the Point object.\n * @param {String} eventType\n * @param {Object} eventArgs Additional event arguments\n * @param {Function} defaultFunction Default event handler\n */\n firePointEvent: function(eventType, eventArgs, defaultFunction) {\n var point = this,\n series = this.series,\n seriesOptions = series.options;\n\n // load event handlers on demand to save time on mouseover/out\n if (seriesOptions.point.events[eventType] || (point.options && point.options.events && point.options.events[eventType])) {\n this.importEvents();\n }\n\n // add default handler if in selection mode\n if (eventType === 'click' && seriesOptions.allowPointSelect) {\n defaultFunction = function(event) {\n // Control key is for Windows, meta (= Cmd key) for Mac, Shift for Opera\n if (point.select) { // Could be destroyed by prior event handlers (#2911)\n point.select(null, event.ctrlKey || event.metaKey || event.shiftKey);\n }\n };\n }\n\n fireEvent(this, eventType, eventArgs, defaultFunction);\n },\n\n /**\n * For certain series types, like pie charts, where individual points can\n * be shown or hidden. \n *\n * @name visible\n * @memberOf Highcharts.Point\n * @type {Boolean}\n */\n visible: true\n };\n\n /**\n * For categorized axes this property holds the category name for the \n * point. For other axes it holds the X value.\n *\n * @name category\n * @memberOf Highcharts.Point\n * @type {String|Number}\n */\n\n /**\n * The percentage for points in a stacked series or pies.\n *\n * @name percentage\n * @memberOf Highcharts.Point\n * @type {Number}\n */\n\n /**\n * The total of values in either a stack for stacked series, or a pie in a pie\n * series.\n *\n * @name total\n * @memberOf Highcharts.Point\n * @type {Number}\n */\n\n /**\n * The x value of the point.\n *\n * @name x\n * @memberOf Highcharts.Point\n * @type {Number}\n */\n\n /**\n * The y value of the point.\n *\n * @name y\n * @memberOf Highcharts.Point\n * @type {Number}\n */\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var addEvent = H.addEvent,\n animObject = H.animObject,\n arrayMax = H.arrayMax,\n arrayMin = H.arrayMin,\n correctFloat = H.correctFloat,\n Date = H.Date,\n defaultOptions = H.defaultOptions,\n defaultPlotOptions = H.defaultPlotOptions,\n defined = H.defined,\n each = H.each,\n erase = H.erase,\n extend = H.extend,\n fireEvent = H.fireEvent,\n grep = H.grep,\n isArray = H.isArray,\n isNumber = H.isNumber,\n isString = H.isString,\n LegendSymbolMixin = H.LegendSymbolMixin, // @todo add as a requirement\n merge = H.merge,\n objectEach = H.objectEach,\n pick = H.pick,\n Point = H.Point, // @todo add as a requirement\n removeEvent = H.removeEvent,\n splat = H.splat,\n SVGElement = H.SVGElement,\n syncTimeout = H.syncTimeout,\n win = H.win;\n\n /**\n * This is the base series prototype that all other series types inherit from.\n * A new series is initiated either through the {@link https://api.highcharts.com/highcharts/series|\n * series} option structure, or after the chart is initiated, through {@link\n * Highcharts.Chart#addSeries}.\n *\n * The object can be accessed in a number of ways. All series and point event\n * handlers give a reference to the `series` object. The chart object has a\n * {@link Highcharts.Chart.series|series} property that is a collection of all\n * the chart's series. The point objects and axis objects also have the same\n * reference.\n * \n * Another way to reference the series programmatically is by `id`. Add an id\n * in the series configuration options, and get the series object by {@link\n * Highcharts.Chart#get}.\n *\n * Configuration options for the series are given in three levels. Options for\n * all series in a chart are given in the {@link https://api.highcharts.com/highcharts/plotOptions.series|\n * plotOptions.series} object. Then options for all series of a specific type\n * are given in the plotOptions of that type, for example `plotOptions.line`.\n * Next, options for one single series are given in the series array, or as\n * arguements to `chart.addSeries`. \n * \n * The data in the series is stored in various arrays.\n *\n * - First, `series.options.data` contains all the original config options for\n * each point whether added by options or methods like `series.addPoint`.\n * - Next, `series.data` contains those values converted to points, but in case\n * the series data length exceeds the `cropThreshold`, or if the data is grouped,\n * `series.data` doesn't contain all the points. It only contains the points that\n * have been created on demand.\n * - Then there's `series.points` that contains all currently visible point\n * objects. In case of cropping, the cropped-away points are not part of this\n * array. The `series.points` array starts at `series.cropStart` compared to\n * `series.data` and `series.options.data`. If however the series data is grouped,\n * these can't be correlated one to one.\n * - `series.xData` and `series.processedXData` contain clean x values, equivalent\n * to `series.data` and `series.points`.\n * - `series.yData` and `series.processedYData` contain clean y values, equivalent\n * to `series.data` and `series.points`.\n *\n * @class Highcharts.Series\n * @param {Highcharts.Chart} chart\n * The chart instance.\n * @param {Object} options\n * The series options.\n */\n H.Series = H.seriesType('line', null, { // base series options\n\n //cursor: 'default',\n //dashStyle: null,\n //linecap: 'round',\n lineWidth: 2,\n //shadow: false,\n\n allowPointSelect: false,\n showCheckbox: false,\n animation: {\n duration: 1000\n },\n //clip: true,\n //connectNulls: false,\n //enableMouseTracking: true,\n events: {},\n //legendIndex: 0,\n // stacking: null,\n marker: {\n\n lineWidth: 0,\n lineColor: '#ffffff',\n //fillColor: null,\n\n //enabled: true,\n //symbol: null,\n radius: 4,\n states: { // states for a single point\n hover: {\n animation: {\n duration: 50\n },\n enabled: true,\n radiusPlus: 2,\n\n lineWidthPlus: 1\n\n },\n\n select: {\n fillColor: '#cccccc',\n lineColor: '#000000',\n lineWidth: 2\n }\n\n }\n },\n point: {\n events: {}\n },\n dataLabels: {\n align: 'center',\n // defer: true,\n // enabled: false,\n formatter: function() {\n return this.y === null ? '' : H.numberFormat(this.y, -1);\n },\n\n style: {\n fontSize: '11px',\n fontWeight: 'bold',\n color: 'contrast',\n textOutline: '1px contrast'\n },\n // backgroundColor: undefined,\n // borderColor: undefined,\n // borderWidth: undefined,\n // shadow: false\n\n verticalAlign: 'bottom', // above singular point\n x: 0,\n y: 0,\n // borderRadius: undefined,\n padding: 5\n },\n // draw points outside the plot area when the number of points is less than\n // this\n cropThreshold: 300,\n pointRange: 0,\n //pointStart: 0,\n //pointInterval: 1,\n //showInLegend: null, // auto = false for linked series\n softThreshold: true,\n states: { // states for the entire series\n hover: {\n //enabled: false,\n animation: {\n duration: 50\n },\n lineWidthPlus: 1,\n marker: {\n // lineWidth: base + 1,\n // radius: base + 1\n },\n halo: {\n size: 10,\n\n opacity: 0.25\n\n }\n },\n select: {\n marker: {}\n }\n },\n stickyTracking: true,\n //tooltip: {\n //pointFormat: '\\u25CF' +\n // '{series.name}: {point.y}'\n //valueDecimals: null,\n //xDateFormat: '%A, %b %e, %Y',\n //valuePrefix: '',\n //ySuffix: ''\n //}\n turboThreshold: 1000,\n // zIndex: null\n findNearestPointBy: 'x'\n\n }, /** @lends Highcharts.Series.prototype */ {\n isCartesian: true,\n pointClass: Point,\n sorted: true, // requires the data to be sorted\n requireSorting: true,\n directTouch: false,\n axisTypes: ['xAxis', 'yAxis'],\n colorCounter: 0,\n // each point's x and y values are stored in this.xData and this.yData\n parallelArrays: ['x', 'y'],\n coll: 'series',\n init: function(chart, options) {\n var series = this,\n events,\n chartSeries = chart.series,\n lastSeries;\n\n /**\n * Read only. The chart that the series belongs to.\n *\n * @name chart\n * @memberOf Series\n * @type {Chart}\n */\n series.chart = chart;\n\n /**\n * Read only. The series' type, like \"line\", \"area\", \"column\" etc. The\n * type in the series options anc can be altered using {@link\n * Series#update}.\n *\n * @name type\n * @memberOf Series\n * @type String\n */\n\n /**\n * Read only. The series' current options. To update, use {@link\n * Series#update}.\n *\n * @name options\n * @memberOf Series\n * @type SeriesOptions\n */\n series.options = options = series.setOptions(options);\n series.linkedSeries = [];\n\n // bind the axes\n series.bindAxes();\n\n // set some variables\n extend(series, {\n /**\n * The series name as given in the options. Defaults to\n * \"Series {n}\".\n *\n * @name name\n * @memberOf Series\n * @type {String}\n */\n name: options.name,\n state: '',\n /**\n * Read only. The series' visibility state as set by {@link\n * Series#show}, {@link Series#hide}, or in the initial\n * configuration.\n *\n * @name visible\n * @memberOf Series\n * @type {Boolean}\n */\n visible: options.visible !== false, // true by default\n /**\n * Read only. The series' selected state as set by {@link\n * Highcharts.Series#select}.\n * \n * @name selected\n * @memberOf Series\n * @type {Boolean}\n */\n selected: options.selected === true // false by default\n });\n\n // register event listeners\n events = options.events;\n\n objectEach(events, function(event, eventType) {\n addEvent(series, eventType, event);\n });\n if (\n (events && events.click) ||\n (\n options.point &&\n options.point.events &&\n options.point.events.click\n ) ||\n options.allowPointSelect\n ) {\n chart.runTrackerClick = true;\n }\n\n series.getColor();\n series.getSymbol();\n\n // Set the data\n each(series.parallelArrays, function(key) {\n series[key + 'Data'] = [];\n });\n series.setData(options.data, false);\n\n // Mark cartesian\n if (series.isCartesian) {\n chart.hasCartesianSeries = true;\n }\n\n // Get the index and register the series in the chart. The index is one\n // more than the current latest series index (#5960).\n if (chartSeries.length) {\n lastSeries = chartSeries[chartSeries.length - 1];\n }\n series._i = pick(lastSeries && lastSeries._i, -1) + 1;\n\n // Insert the series and re-order all series above the insertion point.\n chart.orderSeries(this.insert(chartSeries));\n },\n\n /**\n * Insert the series in a collection with other series, either the chart\n * series or yAxis series, in the correct order according to the index \n * option.\n * @param {Array} collection A collection of series.\n * @returns {Number} The index of the series in the collection.\n */\n insert: function(collection) {\n var indexOption = this.options.index,\n i;\n\n // Insert by index option\n if (isNumber(indexOption)) {\n i = collection.length;\n while (i--) {\n // Loop down until the interted element has higher index\n if (indexOption >=\n pick(collection[i].options.index, collection[i]._i)) {\n collection.splice(i + 1, 0, this);\n break;\n }\n }\n if (i === -1) {\n collection.unshift(this);\n }\n i = i + 1;\n\n // Or just push it to the end\n } else {\n collection.push(this);\n }\n return pick(i, collection.length - 1);\n },\n\n /**\n * Set the xAxis and yAxis properties of cartesian series, and register the\n * series in the `axis.series` array.\n *\n * @function #bindAxes\n * @memberOf Series\n * @returns {void}\n */\n bindAxes: function() {\n var series = this,\n seriesOptions = series.options,\n chart = series.chart,\n axisOptions;\n\n // repeat for xAxis and yAxis\n each(series.axisTypes || [], function(AXIS) {\n\n // loop through the chart's axis objects\n each(chart[AXIS], function(axis) {\n axisOptions = axis.options;\n\n // apply if the series xAxis or yAxis option mathches the number\n // of the axis, or if undefined, use the first axis\n if (\n seriesOptions[AXIS] === axisOptions.index ||\n (\n seriesOptions[AXIS] !== undefined &&\n seriesOptions[AXIS] === axisOptions.id\n ) ||\n (\n seriesOptions[AXIS] === undefined &&\n axisOptions.index === 0\n )\n ) {\n\n // register this series in the axis.series lookup\n series.insert(axis.series);\n\n // set this series.xAxis or series.yAxis reference\n /**\n * Read only. The unique xAxis object associated with the\n * series.\n *\n * @name xAxis\n * @memberOf Series\n * @type Axis\n */\n /**\n * Read only. The unique yAxis object associated with the\n * series.\n *\n * @name yAxis\n * @memberOf Series\n * @type Axis\n */\n series[AXIS] = axis;\n\n // mark dirty for redraw\n axis.isDirty = true;\n }\n });\n\n // The series needs an X and an Y axis\n if (!series[AXIS] && series.optionalAxis !== AXIS) {\n H.error(18, true);\n }\n\n });\n },\n\n /**\n * For simple series types like line and column, the data values are held in\n * arrays like xData and yData for quick lookup to find extremes and more.\n * For multidimensional series like bubble and map, this can be extended\n * with arrays like zData and valueData by adding to the\n * series.parallelArrays array.\n */\n updateParallelArrays: function(point, i) {\n var series = point.series,\n args = arguments,\n fn = isNumber(i) ?\n // Insert the value in the given position\n function(key) {\n var val = key === 'y' && series.toYData ?\n series.toYData(point) :\n point[key];\n series[key + 'Data'][i] = val;\n } :\n // Apply the method specified in i with the following arguments\n // as arguments\n function(key) {\n Array.prototype[i].apply(\n series[key + 'Data'],\n Array.prototype.slice.call(args, 2)\n );\n };\n\n each(series.parallelArrays, fn);\n },\n\n /**\n * Return an auto incremented x value based on the pointStart and\n * pointInterval options. This is only used if an x value is not given for\n * the point that calls autoIncrement.\n */\n autoIncrement: function() {\n\n var options = this.options,\n xIncrement = this.xIncrement,\n date,\n pointInterval,\n pointIntervalUnit = options.pointIntervalUnit;\n\n xIncrement = pick(xIncrement, options.pointStart, 0);\n\n this.pointInterval = pointInterval = pick(\n this.pointInterval,\n options.pointInterval,\n 1\n );\n\n // Added code for pointInterval strings\n if (pointIntervalUnit) {\n date = new Date(xIncrement);\n\n if (pointIntervalUnit === 'day') {\n date = +date[Date.hcSetDate](\n date[Date.hcGetDate]() + pointInterval\n );\n } else if (pointIntervalUnit === 'month') {\n date = +date[Date.hcSetMonth](\n date[Date.hcGetMonth]() + pointInterval\n );\n } else if (pointIntervalUnit === 'year') {\n date = +date[Date.hcSetFullYear](\n date[Date.hcGetFullYear]() + pointInterval\n );\n }\n pointInterval = date - xIncrement;\n\n }\n\n this.xIncrement = xIncrement + pointInterval;\n return xIncrement;\n },\n\n /**\n * Set the series options by merging from the options tree\n * @param {Object} itemOptions\n */\n setOptions: function(itemOptions) {\n var chart = this.chart,\n chartOptions = chart.options,\n plotOptions = chartOptions.plotOptions,\n userOptions = chart.userOptions || {},\n userPlotOptions = userOptions.plotOptions || {},\n typeOptions = plotOptions[this.type],\n options,\n zones;\n\n this.userOptions = itemOptions;\n\n // General series options take precedence over type options because\n // otherwise, default type options like column.animation would be\n // overwritten by the general option. But issues have been raised here\n // (#3881), and the solution may be to distinguish between default\n // option and userOptions like in the tooltip below.\n options = merge(\n typeOptions,\n plotOptions.series,\n itemOptions\n );\n\n // The tooltip options are merged between global and series specific\n // options. Importance order asscendingly:\n // globals: (1)tooltip, (2)plotOptions.series, (3)plotOptions[this.type]\n // init userOptions with possible later updates: 4-6 like 1-3 and\n // (7)this series options\n this.tooltipOptions = merge(\n defaultOptions.tooltip, // 1\n defaultOptions.plotOptions.series &&\n defaultOptions.plotOptions.series.tooltip, // 2\n defaultOptions.plotOptions[this.type].tooltip, // 3\n chartOptions.tooltip.userOptions, // 4\n plotOptions.series && plotOptions.series.tooltip, // 5\n plotOptions[this.type].tooltip, // 6\n itemOptions.tooltip // 7\n );\n\n // When shared tooltip, stickyTracking is true by default,\n // unless user says otherwise.\n this.stickyTracking = pick(\n itemOptions.stickyTracking,\n userPlotOptions[this.type] &&\n userPlotOptions[this.type].stickyTracking,\n userPlotOptions.series && userPlotOptions.series.stickyTracking,\n (\n this.tooltipOptions.shared && !this.noSharedTooltip ?\n true :\n options.stickyTracking\n )\n );\n\n // Delete marker object if not allowed (#1125)\n if (typeOptions.marker === null) {\n delete options.marker;\n }\n\n // Handle color zones\n this.zoneAxis = options.zoneAxis;\n zones = this.zones = (options.zones || []).slice();\n if (\n (options.negativeColor || options.negativeFillColor) &&\n !options.zones\n ) {\n zones.push({\n value: options[this.zoneAxis + 'Threshold'] ||\n options.threshold ||\n 0,\n className: 'highcharts-negative',\n\n color: options.negativeColor,\n fillColor: options.negativeFillColor\n\n });\n }\n if (zones.length) { // Push one extra zone for the rest\n if (defined(zones[zones.length - 1].value)) {\n zones.push({\n\n color: this.color,\n fillColor: this.fillColor\n\n });\n }\n }\n return options;\n },\n\n getCyclic: function(prop, value, defaults) {\n var i,\n chart = this.chart,\n userOptions = this.userOptions,\n indexName = prop + 'Index',\n counterName = prop + 'Counter',\n len = defaults ? defaults.length : pick(\n chart.options.chart[prop + 'Count'],\n chart[prop + 'Count']\n ),\n setting;\n\n if (!value) {\n // Pick up either the colorIndex option, or the _colorIndex after\n // Series.update()\n setting = pick(\n userOptions[indexName],\n userOptions['_' + indexName]\n );\n if (defined(setting)) { // after Series.update()\n i = setting;\n } else {\n // #6138\n if (!chart.series.length) {\n chart[counterName] = 0;\n }\n userOptions['_' + indexName] = i = chart[counterName] % len;\n chart[counterName] += 1;\n }\n if (defaults) {\n value = defaults[i];\n }\n }\n // Set the colorIndex\n if (i !== undefined) {\n this[indexName] = i;\n }\n this[prop] = value;\n },\n\n /**\n * Get the series' color\n */\n\n getColor: function() {\n if (this.options.colorByPoint) {\n // #4359, selected slice got series.color even when colorByPoint was\n // set.\n this.options.color = null;\n } else {\n this.getCyclic(\n 'color',\n this.options.color || defaultPlotOptions[this.type].color,\n this.chart.options.colors\n );\n }\n },\n\n /**\n * Get the series' symbol\n */\n getSymbol: function() {\n var seriesMarkerOption = this.options.marker;\n\n this.getCyclic(\n 'symbol',\n seriesMarkerOption.symbol,\n this.chart.options.symbols\n );\n },\n\n drawLegendSymbol: LegendSymbolMixin.drawLineMarker,\n\n /**\n * Apply a new set of data to the series and optionally redraw it. The new\n * data array is passed by reference (except in case of `updatePoints`), and\n * may later be mutated when updating the chart data.\n * \n * Note the difference in behaviour when setting the same amount of points,\n * or a different amount of points, as handled by the `updatePoints`\n * parameter. \n * \n * @param {SeriesDataOptions} data\n * Takes an array of data in the same format as described under\n * `seriesdata` for the given series type.\n * @param {Boolean} [redraw=true]\n * Whether to redraw the chart after the series is altered. If doing\n * more operations on the chart, it is a good idea to set redraw to\n * false and call {@link Chart#redraw} after.\n * @param {AnimationOptions} [animation]\n * When the updated data is the same length as the existing data,\n * points will be updated by default, and animation visualizes how\n * the points are changed. Set false to disable animation, or a\n * configuration object to set duration or easing.\n * @param {Boolean} [updatePoints=true]\n * When the updated data is the same length as the existing data,\n * points will be updated instead of replaced. This allows updating\n * with animation and performs better. In this case, the original\n * array is not passed by reference. Set false to prevent.\n *\n * @sample highcharts/members/series-setdata/\n * Set new data from a button\n * @sample highcharts/members/series-setdata-pie/\n * Set data in a pie\n * @sample stock/members/series-setdata/\n * Set new data in Highstock\n * @sample maps/members/series-setdata/\n * Set new data in Highmaps\n */\n setData: function(data, redraw, animation, updatePoints) {\n var series = this,\n oldData = series.points,\n oldDataLength = (oldData && oldData.length) || 0,\n dataLength,\n options = series.options,\n chart = series.chart,\n firstPoint = null,\n xAxis = series.xAxis,\n i,\n turboThreshold = options.turboThreshold,\n pt,\n xData = this.xData,\n yData = this.yData,\n pointArrayMap = series.pointArrayMap,\n valueCount = pointArrayMap && pointArrayMap.length;\n\n data = data || [];\n dataLength = data.length;\n redraw = pick(redraw, true);\n\n // If the point count is the same as is was, just run Point.update which\n // is cheaper, allows animation, and keeps references to points.\n if (\n updatePoints !== false &&\n dataLength &&\n oldDataLength === dataLength &&\n !series.cropped &&\n !series.hasGroupedData &&\n series.visible\n ) {\n each(data, function(point, i) {\n // .update doesn't exist on a linked, hidden series (#3709)\n if (oldData[i].update && point !== options.data[i]) {\n oldData[i].update(point, false, null, false);\n }\n });\n\n } else {\n\n // Reset properties\n series.xIncrement = null;\n\n series.colorCounter = 0; // for series with colorByPoint (#1547)\n\n // Update parallel arrays\n each(this.parallelArrays, function(key) {\n series[key + 'Data'].length = 0;\n });\n\n // In turbo mode, only one- or twodimensional arrays of numbers are\n // allowed. The first value is tested, and we assume that all the\n // rest are defined the same way. Although the 'for' loops are\n // similar, they are repeated inside each if-else conditional for\n // max performance.\n if (turboThreshold && dataLength > turboThreshold) {\n\n // find the first non-null point\n i = 0;\n while (firstPoint === null && i < dataLength) {\n firstPoint = data[i];\n i++;\n }\n\n\n if (isNumber(firstPoint)) { // assume all points are numbers\n for (i = 0; i < dataLength; i++) {\n xData[i] = this.autoIncrement();\n yData[i] = data[i];\n }\n\n // Assume all points are arrays when first point is\n } else if (isArray(firstPoint)) {\n if (valueCount) { // [x, low, high] or [x, o, h, l, c]\n for (i = 0; i < dataLength; i++) {\n pt = data[i];\n xData[i] = pt[0];\n yData[i] = pt.slice(1, valueCount + 1);\n }\n } else { // [x, y]\n for (i = 0; i < dataLength; i++) {\n pt = data[i];\n xData[i] = pt[0];\n yData[i] = pt[1];\n }\n }\n } else {\n // Highcharts expects configs to be numbers or arrays in\n // turbo mode\n H.error(12);\n }\n } else {\n for (i = 0; i < dataLength; i++) {\n if (data[i] !== undefined) { // stray commas in oldIE\n pt = {\n series: series\n };\n series.pointClass.prototype.applyOptions.apply(\n pt, [data[i]]\n );\n series.updateParallelArrays(pt, i);\n }\n }\n }\n\n // Forgetting to cast strings to numbers is a common caveat when\n // handling CSV or JSON\n if (isString(yData[0])) {\n H.error(14, true);\n }\n\n /**\n * Read only. An array containing the series' data point objects. To\n * modify the data, use {@link Highcharts.Series#setData} or {@link\n * Highcharts.Point#update}.\n *\n * @name data\n * @memberOf Highcharts.Series\n * @type {Array.}\n */\n series.data = [];\n series.options.data = series.userOptions.data = data;\n\n // destroy old points\n i = oldDataLength;\n while (i--) {\n if (oldData[i] && oldData[i].destroy) {\n oldData[i].destroy();\n }\n }\n\n // reset minRange (#878)\n if (xAxis) {\n xAxis.minRange = xAxis.userMinRange;\n }\n\n // redraw\n series.isDirty = chart.isDirtyBox = true;\n series.isDirtyData = !!oldData;\n animation = false;\n }\n\n // Typically for pie series, points need to be processed and generated\n // prior to rendering the legend\n if (options.legendType === 'point') {\n this.processData();\n this.generatePoints();\n }\n\n if (redraw) {\n chart.redraw(animation);\n }\n },\n\n /**\n * Process the data by cropping away unused data points if the series is\n * longer than the crop threshold. This saves computing time for large\n * series.\n */\n processData: function(force) {\n var series = this,\n processedXData = series.xData, // copied during slice operation\n processedYData = series.yData,\n dataLength = processedXData.length,\n croppedData,\n cropStart = 0,\n cropped,\n distance,\n closestPointRange,\n xAxis = series.xAxis,\n i, // loop variable\n options = series.options,\n cropThreshold = options.cropThreshold,\n getExtremesFromAll =\n series.getExtremesFromAll ||\n options.getExtremesFromAll, // #4599\n isCartesian = series.isCartesian,\n xExtremes,\n val2lin = xAxis && xAxis.val2lin,\n isLog = xAxis && xAxis.isLog,\n min,\n max;\n\n // If the series data or axes haven't changed, don't go through this.\n // Return false to pass the message on to override methods like in data\n // grouping.\n if (\n isCartesian &&\n !series.isDirty &&\n !xAxis.isDirty &&\n !series.yAxis.isDirty &&\n !force\n ) {\n return false;\n }\n\n if (xAxis) {\n xExtremes = xAxis.getExtremes(); // corrected for log axis (#3053)\n min = xExtremes.min;\n max = xExtremes.max;\n }\n\n // optionally filter out points outside the plot area\n if (\n isCartesian &&\n series.sorted &&\n !getExtremesFromAll &&\n (!cropThreshold || dataLength > cropThreshold || series.forceCrop)\n ) {\n\n // it's outside current extremes\n if (\n processedXData[dataLength - 1] < min ||\n processedXData[0] > max\n ) {\n processedXData = [];\n processedYData = [];\n\n // only crop if it's actually spilling out\n } else if (\n processedXData[0] < min ||\n processedXData[dataLength - 1] > max\n ) {\n croppedData = this.cropData(\n series.xData,\n series.yData,\n min,\n max\n );\n processedXData = croppedData.xData;\n processedYData = croppedData.yData;\n cropStart = croppedData.start;\n cropped = true;\n }\n }\n\n\n // Find the closest distance between processed points\n i = processedXData.length || 1;\n while (--i) {\n distance = isLog ?\n val2lin(processedXData[i]) - val2lin(processedXData[i - 1]) :\n processedXData[i] - processedXData[i - 1];\n\n if (\n distance > 0 &&\n (\n closestPointRange === undefined ||\n distance < closestPointRange\n )\n ) {\n closestPointRange = distance;\n\n // Unsorted data is not supported by the line tooltip, as well as\n // data grouping and navigation in Stock charts (#725) and width\n // calculation of columns (#1900)\n } else if (distance < 0 && series.requireSorting) {\n H.error(15);\n }\n }\n\n // Record the properties\n series.cropped = cropped; // undefined or true\n series.cropStart = cropStart;\n series.processedXData = processedXData;\n series.processedYData = processedYData;\n\n series.closestPointRange = closestPointRange;\n\n },\n\n /**\n * Iterate over xData and crop values between min and max. Returns object\n * containing crop start/end cropped xData with corresponding part of yData,\n * dataMin and dataMax within the cropped range\n */\n cropData: function(xData, yData, min, max) {\n var dataLength = xData.length,\n cropStart = 0,\n cropEnd = dataLength,\n // line-type series need one point outside\n cropShoulder = pick(this.cropShoulder, 1),\n i,\n j;\n\n // iterate up to find slice start\n for (i = 0; i < dataLength; i++) {\n if (xData[i] >= min) {\n cropStart = Math.max(0, i - cropShoulder);\n break;\n }\n }\n\n // proceed to find slice end\n for (j = i; j < dataLength; j++) {\n if (xData[j] > max) {\n cropEnd = j + cropShoulder;\n break;\n }\n }\n\n return {\n xData: xData.slice(cropStart, cropEnd),\n yData: yData.slice(cropStart, cropEnd),\n start: cropStart,\n end: cropEnd\n };\n },\n\n\n /**\n * Generate the data point after the data has been processed by cropping\n * away unused points and optionally grouped in Highcharts Stock.\n */\n generatePoints: function() {\n var series = this,\n options = series.options,\n dataOptions = options.data,\n data = series.data,\n dataLength,\n processedXData = series.processedXData,\n processedYData = series.processedYData,\n PointClass = series.pointClass,\n processedDataLength = processedXData.length,\n cropStart = series.cropStart || 0,\n cursor,\n hasGroupedData = series.hasGroupedData,\n keys = options.keys,\n point,\n points = [],\n i;\n\n if (!data && !hasGroupedData) {\n var arr = [];\n arr.length = dataOptions.length;\n data = series.data = arr;\n }\n\n if (keys && hasGroupedData) {\n // grouped data has already applied keys (#6590)\n series.options.keys = false;\n }\n\n for (i = 0; i < processedDataLength; i++) {\n cursor = cropStart + i;\n if (!hasGroupedData) {\n point = data[cursor];\n if (!point && dataOptions[cursor] !== undefined) { // #970\n data[cursor] = point = (new PointClass()).init(\n series,\n dataOptions[cursor],\n processedXData[i]\n );\n }\n } else {\n // splat the y data in case of ohlc data array\n point = (new PointClass()).init(\n series, [processedXData[i]].concat(splat(processedYData[i]))\n );\n\n /**\n * Highstock only. If a point object is created by data\n * grouping, it doesn't reflect actual points in the raw data.\n * In this case, the `dataGroup` property holds information\n * that points back to the raw data.\n *\n * - `dataGroup.start` is the index of the first raw data point\n * in the group.\n * - `dataGroup.length` is the amount of points in the group.\n *\n * @name dataGroup\n * @memberOf Point\n * @type {Object}\n * \n */\n point.dataGroup = series.groupMap[i];\n }\n if (point) { // #6279\n point.index = cursor; // For faster access in Point.update\n points[i] = point;\n }\n }\n\n // restore keys options (#6590)\n series.options.keys = keys;\n\n // Hide cropped-away points - this only runs when the number of points\n // is above cropThreshold, or when swithching view from non-grouped\n // data to grouped data (#637)\n if (\n data &&\n (\n processedDataLength !== (dataLength = data.length) ||\n hasGroupedData\n )\n ) {\n for (i = 0; i < dataLength; i++) {\n // when has grouped data, clear all points\n if (i === cropStart && !hasGroupedData) {\n i += processedDataLength;\n }\n if (data[i]) {\n data[i].destroyElements();\n data[i].plotX = undefined; // #1003\n }\n }\n }\n\n series.data = data;\n series.points = points;\n },\n\n /**\n * Calculate Y extremes for visible data\n */\n getExtremes: function(yData) {\n var xAxis = this.xAxis,\n yAxis = this.yAxis,\n xData = this.processedXData,\n yDataLength,\n activeYData = [],\n activeCounter = 0,\n // #2117, need to compensate for log X axis\n xExtremes = xAxis.getExtremes(),\n xMin = xExtremes.min,\n xMax = xExtremes.max,\n validValue,\n withinRange,\n x,\n y,\n i,\n j;\n\n yData = yData || this.stackedYData || this.processedYData || [];\n yDataLength = yData.length;\n\n for (i = 0; i < yDataLength; i++) {\n\n x = xData[i];\n y = yData[i];\n\n // For points within the visible range, including the first point\n // outside the visible range, consider y extremes\n validValue =\n (isNumber(y, true) || isArray(y)) &&\n (!yAxis.positiveValuesOnly || (y.length || y > 0));\n withinRange =\n this.getExtremesFromAll ||\n this.options.getExtremesFromAll ||\n this.cropped ||\n ((xData[i] || x) >= xMin && (xData[i] || x) <= xMax);\n\n if (validValue && withinRange) {\n\n j = y.length;\n if (j) { // array, like ohlc or range data\n while (j--) {\n if (y[j] !== null) {\n activeYData[activeCounter++] = y[j];\n }\n }\n } else {\n activeYData[activeCounter++] = y;\n }\n }\n }\n\n this.dataMin = arrayMin(activeYData);\n this.dataMax = arrayMax(activeYData);\n },\n\n /**\n * Translate data points from raw data values to chart specific positioning\n * data needed later in drawPoints, drawGraph and drawTracker.\n *\n * @function #translate\n * @memberOf Series\n * @returns {void}\n */\n translate: function() {\n if (!this.processedXData) { // hidden series\n this.processData();\n }\n this.generatePoints();\n var series = this,\n options = series.options,\n stacking = options.stacking,\n xAxis = series.xAxis,\n categories = xAxis.categories,\n yAxis = series.yAxis,\n points = series.points,\n dataLength = points.length,\n hasModifyValue = !!series.modifyValue,\n i,\n pointPlacement = options.pointPlacement,\n dynamicallyPlaced =\n pointPlacement === 'between' ||\n isNumber(pointPlacement),\n threshold = options.threshold,\n stackThreshold = options.startFromThreshold ? threshold : 0,\n plotX,\n plotY,\n lastPlotX,\n stackIndicator,\n closestPointRangePx = Number.MAX_VALUE;\n\n // Point placement is relative to each series pointRange (#5889)\n if (pointPlacement === 'between') {\n pointPlacement = 0.5;\n }\n if (isNumber(pointPlacement)) {\n pointPlacement *= pick(options.pointRange || xAxis.pointRange);\n }\n\n // Translate each point\n for (i = 0; i < dataLength; i++) {\n var point = points[i],\n xValue = point.x,\n yValue = point.y,\n yBottom = point.low,\n stack = stacking && yAxis.stacks[(\n series.negStacks &&\n yValue < (stackThreshold ? 0 : threshold) ? '-' : ''\n ) + series.stackKey],\n pointStack,\n stackValues;\n\n // Discard disallowed y values for log axes (#3434)\n if (yAxis.positiveValuesOnly && yValue !== null && yValue <= 0) {\n point.isNull = true;\n }\n\n // Get the plotX translation\n point.plotX = plotX = correctFloat( // #5236\n Math.min(Math.max(-1e5, xAxis.translate(\n xValue,\n 0,\n 0,\n 0,\n 1,\n pointPlacement,\n this.type === 'flags'\n )), 1e5) // #3923\n );\n\n // Calculate the bottom y value for stacked series\n if (\n stacking &&\n series.visible &&\n !point.isNull &&\n stack &&\n stack[xValue]\n ) {\n stackIndicator = series.getStackIndicator(\n stackIndicator,\n xValue,\n series.index\n );\n pointStack = stack[xValue];\n stackValues = pointStack.points[stackIndicator.key];\n yBottom = stackValues[0];\n yValue = stackValues[1];\n\n if (\n yBottom === stackThreshold &&\n stackIndicator.key === stack[xValue].base\n ) {\n yBottom = pick(threshold, yAxis.min);\n }\n if (yAxis.positiveValuesOnly && yBottom <= 0) { // #1200, #1232\n yBottom = null;\n }\n\n point.total = point.stackTotal = pointStack.total;\n point.percentage =\n pointStack.total &&\n (point.y / pointStack.total * 100);\n point.stackY = yValue;\n\n // Place the stack label\n pointStack.setOffset(\n series.pointXOffset || 0,\n series.barW || 0\n );\n\n }\n\n // Set translated yBottom or remove it\n point.yBottom = defined(yBottom) ?\n yAxis.translate(yBottom, 0, 1, 0, 1) :\n null;\n\n // general hook, used for Highstock compare mode\n if (hasModifyValue) {\n yValue = series.modifyValue(yValue, point);\n }\n\n // Set the the plotY value, reset it for redraws\n point.plotY = plotY =\n (typeof yValue === 'number' && yValue !== Infinity) ?\n Math.min(Math.max(-1e5,\n yAxis.translate(yValue, 0, 1, 0, 1)), 1e5) : // #3201\n undefined;\n\n point.isInside =\n plotY !== undefined &&\n plotY >= 0 &&\n plotY <= yAxis.len && // #3519\n plotX >= 0 &&\n plotX <= xAxis.len;\n\n\n // Set client related positions for mouse tracking\n point.clientX = dynamicallyPlaced ?\n correctFloat(\n xAxis.translate(xValue, 0, 0, 0, 1, pointPlacement)\n ) :\n plotX; // #1514, #5383, #5518\n\n point.negative = point.y < (threshold || 0);\n\n // some API data\n point.category = categories && categories[point.x] !== undefined ?\n categories[point.x] : point.x;\n\n // Determine auto enabling of markers (#3635, #5099)\n if (!point.isNull) {\n if (lastPlotX !== undefined) {\n closestPointRangePx = Math.min(\n closestPointRangePx,\n Math.abs(plotX - lastPlotX)\n );\n }\n lastPlotX = plotX;\n }\n\n // Find point zone\n point.zone = this.zones.length && point.getZone();\n }\n series.closestPointRangePx = closestPointRangePx;\n },\n\n /**\n * Return the series points with null points filtered out\n */\n getValidPoints: function(points, insideOnly) {\n var chart = this.chart;\n // #3916, #5029, #5085\n return grep(points || this.points || [], function isValidPoint(point) {\n if (insideOnly && !chart.isInsidePlot(\n point.plotX,\n point.plotY,\n chart.inverted\n )) {\n return false;\n }\n return !point.isNull;\n });\n },\n\n /**\n * Set the clipping for the series. For animated series it is called twice,\n * first to initiate animating the clip then the second time without the\n * animation to set the final clip.\n */\n setClip: function(animation) {\n var chart = this.chart,\n options = this.options,\n renderer = chart.renderer,\n inverted = chart.inverted,\n seriesClipBox = this.clipBox,\n clipBox = seriesClipBox || chart.clipBox,\n sharedClipKey =\n this.sharedClipKey || [\n '_sharedClip',\n animation && animation.duration,\n animation && animation.easing,\n clipBox.height,\n options.xAxis,\n options.yAxis\n ].join(','), // #4526\n clipRect = chart[sharedClipKey],\n markerClipRect = chart[sharedClipKey + 'm'];\n\n // If a clipping rectangle with the same properties is currently present\n // in the chart, use that.\n if (!clipRect) {\n\n // When animation is set, prepare the initial positions\n if (animation) {\n clipBox.width = 0;\n\n chart[sharedClipKey + 'm'] = markerClipRect = renderer.clipRect(-99, // include the width of the first marker\n inverted ? -chart.plotLeft : -chart.plotTop,\n 99,\n inverted ? chart.chartWidth : chart.chartHeight\n );\n }\n chart[sharedClipKey] = clipRect = renderer.clipRect(clipBox);\n // Create hashmap for series indexes\n clipRect.count = {\n length: 0\n };\n\n }\n if (animation) {\n if (!clipRect.count[this.index]) {\n clipRect.count[this.index] = true;\n clipRect.count.length += 1;\n }\n }\n\n if (options.clip !== false) {\n this.group.clip(animation || seriesClipBox ? clipRect : chart.clipRect);\n this.markerGroup.clip(markerClipRect);\n this.sharedClipKey = sharedClipKey;\n }\n\n // Remove the shared clipping rectangle when all series are shown\n if (!animation) {\n if (clipRect.count[this.index]) {\n delete clipRect.count[this.index];\n clipRect.count.length -= 1;\n }\n\n if (clipRect.count.length === 0 && sharedClipKey && chart[sharedClipKey]) {\n if (!seriesClipBox) {\n chart[sharedClipKey] = chart[sharedClipKey].destroy();\n }\n if (chart[sharedClipKey + 'm']) {\n chart[sharedClipKey + 'm'] = chart[sharedClipKey + 'm'].destroy();\n }\n }\n }\n },\n\n /**\n * Animate in the series\n */\n animate: function(init) {\n var series = this,\n chart = series.chart,\n clipRect,\n animation = animObject(series.options.animation),\n sharedClipKey;\n\n // Initialize the animation. Set up the clipping rectangle.\n if (init) {\n\n series.setClip(animation);\n\n // Run the animation\n } else {\n sharedClipKey = this.sharedClipKey;\n clipRect = chart[sharedClipKey];\n if (clipRect) {\n clipRect.animate({\n width: chart.plotSizeX\n }, animation);\n }\n if (chart[sharedClipKey + 'm']) {\n chart[sharedClipKey + 'm'].animate({\n width: chart.plotSizeX + 99\n }, animation);\n }\n\n // Delete this function to allow it only once\n series.animate = null;\n\n }\n },\n\n /**\n * This runs after animation to land on the final plot clipping\n */\n afterAnimate: function() {\n this.setClip();\n fireEvent(this, 'afterAnimate');\n },\n\n /**\n * Draw the markers.\n *\n * @function #drawPoints\n * @memberOf Series\n * @returns {void}\n */\n drawPoints: function() {\n var series = this,\n points = series.points,\n chart = series.chart,\n plotY,\n i,\n point,\n symbol,\n graphic,\n options = series.options,\n seriesMarkerOptions = options.marker,\n pointMarkerOptions,\n hasPointMarker,\n enabled,\n isInside,\n markerGroup = series[series.specialGroup] || series.markerGroup,\n xAxis = series.xAxis,\n markerAttribs,\n globallyEnabled = pick(\n seriesMarkerOptions.enabled,\n xAxis.isRadial ? true : null,\n // Use larger or equal as radius is null in bubbles (#6321)\n series.closestPointRangePx >= 2 * seriesMarkerOptions.radius\n );\n\n if (seriesMarkerOptions.enabled !== false || series._hasPointMarkers) {\n\n for (i = 0; i < points.length; i++) {\n point = points[i];\n plotY = point.plotY;\n graphic = point.graphic;\n pointMarkerOptions = point.marker || {};\n hasPointMarker = !!point.marker;\n enabled = (globallyEnabled && pointMarkerOptions.enabled === undefined) || pointMarkerOptions.enabled;\n isInside = point.isInside;\n\n // only draw the point if y is defined\n if (enabled && isNumber(plotY) && point.y !== null) {\n\n // Shortcuts\n symbol = pick(pointMarkerOptions.symbol, series.symbol);\n point.hasImage = symbol.indexOf('url') === 0;\n\n markerAttribs = series.markerAttribs(\n point,\n point.selected && 'select'\n );\n\n if (graphic) { // update\n graphic[isInside ? 'show' : 'hide'](true) // Since the marker group isn't clipped, each individual marker must be toggled\n .animate(markerAttribs);\n } else if (isInside && (markerAttribs.width > 0 || point.hasImage)) {\n point.graphic = graphic = chart.renderer.symbol(\n symbol,\n markerAttribs.x,\n markerAttribs.y,\n markerAttribs.width,\n markerAttribs.height,\n hasPointMarker ? pointMarkerOptions : seriesMarkerOptions\n )\n .add(markerGroup);\n }\n\n\n // Presentational attributes\n if (graphic) {\n graphic.attr(series.pointAttribs(point, point.selected && 'select'));\n }\n\n\n if (graphic) {\n graphic.addClass(point.getClassName(), true);\n }\n\n } else if (graphic) {\n point.graphic = graphic.destroy(); // #1269\n }\n }\n }\n\n },\n\n /**\n * Get non-presentational attributes for the point.\n */\n markerAttribs: function(point, state) {\n var seriesMarkerOptions = this.options.marker,\n seriesStateOptions,\n pointMarkerOptions = point.marker || {},\n pointStateOptions,\n radius = pick(\n pointMarkerOptions.radius,\n seriesMarkerOptions.radius\n ),\n attribs;\n\n // Handle hover and select states\n if (state) {\n seriesStateOptions = seriesMarkerOptions.states[state];\n pointStateOptions = pointMarkerOptions.states &&\n pointMarkerOptions.states[state];\n\n radius = pick(\n pointStateOptions && pointStateOptions.radius,\n seriesStateOptions && seriesStateOptions.radius,\n radius + (seriesStateOptions && seriesStateOptions.radiusPlus || 0)\n );\n }\n\n if (point.hasImage) {\n radius = 0; // and subsequently width and height is not set\n }\n\n attribs = {\n x: Math.floor(point.plotX) - radius, // Math.floor for #1843\n y: point.plotY - radius\n };\n\n if (radius) {\n attribs.width = attribs.height = 2 * radius;\n }\n\n return attribs;\n\n },\n\n\n /**\n * Get presentational attributes for marker-based series (line, spline, scatter, bubble, mappoint...)\n */\n pointAttribs: function(point, state) {\n var seriesMarkerOptions = this.options.marker,\n seriesStateOptions,\n pointOptions = point && point.options,\n pointMarkerOptions = (pointOptions && pointOptions.marker) || {},\n pointStateOptions,\n color = this.color,\n pointColorOption = pointOptions && pointOptions.color,\n pointColor = point && point.color,\n strokeWidth = pick(\n pointMarkerOptions.lineWidth,\n seriesMarkerOptions.lineWidth\n ),\n zoneColor = point && point.zone && point.zone.color,\n fill,\n stroke;\n\n color = pointColorOption || zoneColor || pointColor || color;\n fill = pointMarkerOptions.fillColor || seriesMarkerOptions.fillColor || color;\n stroke = pointMarkerOptions.lineColor || seriesMarkerOptions.lineColor || color;\n\n // Handle hover and select states\n if (state) {\n seriesStateOptions = seriesMarkerOptions.states[state];\n pointStateOptions = (pointMarkerOptions.states && pointMarkerOptions.states[state]) || {};\n strokeWidth = pick(\n pointStateOptions.lineWidth,\n seriesStateOptions.lineWidth,\n strokeWidth + pick(\n pointStateOptions.lineWidthPlus,\n seriesStateOptions.lineWidthPlus,\n 0\n )\n );\n fill = pointStateOptions.fillColor || seriesStateOptions.fillColor || fill;\n stroke = pointStateOptions.lineColor || seriesStateOptions.lineColor || stroke;\n }\n\n return {\n 'stroke': stroke,\n 'stroke-width': strokeWidth,\n 'fill': fill\n };\n },\n\n /**\n * Clear DOM objects and free up memory\n */\n destroy: function() {\n var series = this,\n chart = series.chart,\n issue134 = /AppleWebKit\\/533/.test(win.navigator.userAgent),\n destroy,\n i,\n data = series.data || [],\n point,\n axis;\n\n // add event hook\n fireEvent(series, 'destroy');\n\n // remove all events\n removeEvent(series);\n\n // erase from axes\n each(series.axisTypes || [], function(AXIS) {\n axis = series[AXIS];\n if (axis && axis.series) {\n erase(axis.series, series);\n axis.isDirty = axis.forceRedraw = true;\n }\n });\n\n // remove legend items\n if (series.legendItem) {\n series.chart.legend.destroyItem(series);\n }\n\n // destroy all points with their elements\n i = data.length;\n while (i--) {\n point = data[i];\n if (point && point.destroy) {\n point.destroy();\n }\n }\n series.points = null;\n\n // Clear the animation timeout if we are destroying the series during initial animation\n clearTimeout(series.animationTimeout);\n\n // Destroy all SVGElements associated to the series\n objectEach(series, function(val, prop) {\n if (val instanceof SVGElement && !val.survive) { // Survive provides a hook for not destroying\n\n // issue 134 workaround\n destroy = issue134 && prop === 'group' ?\n 'hide' :\n 'destroy';\n\n val[destroy]();\n }\n });\n\n // remove from hoverSeries\n if (chart.hoverSeries === series) {\n chart.hoverSeries = null;\n }\n erase(chart.series, series);\n chart.orderSeries();\n\n // clear all members\n objectEach(series, function(val, prop) {\n delete series[prop];\n });\n },\n\n /**\n * Get the graph path\n */\n getGraphPath: function(points, nullsAsZeroes, connectCliffs) {\n var series = this,\n options = series.options,\n step = options.step,\n reversed,\n graphPath = [],\n xMap = [],\n gap;\n\n points = points || series.points;\n\n // Bottom of a stack is reversed\n reversed = points.reversed;\n if (reversed) {\n points.reverse();\n }\n // Reverse the steps (#5004)\n step = {\n right: 1,\n center: 2\n }[step] || (step && 3);\n if (step && reversed) {\n step = 4 - step;\n }\n\n // Remove invalid points, especially in spline (#5015)\n if (options.connectNulls && !nullsAsZeroes && !connectCliffs) {\n points = this.getValidPoints(points);\n }\n\n // Build the line\n each(points, function(point, i) {\n\n var plotX = point.plotX,\n plotY = point.plotY,\n lastPoint = points[i - 1],\n pathToPoint; // the path to this point from the previous\n\n if ((point.leftCliff || (lastPoint && lastPoint.rightCliff)) && !connectCliffs) {\n gap = true; // ... and continue\n }\n\n // Line series, nullsAsZeroes is not handled\n if (point.isNull && !defined(nullsAsZeroes) && i > 0) {\n gap = !options.connectNulls;\n\n // Area series, nullsAsZeroes is set\n } else if (point.isNull && !nullsAsZeroes) {\n gap = true;\n\n } else {\n\n if (i === 0 || gap) {\n pathToPoint = ['M', point.plotX, point.plotY];\n\n } else if (series.getPointSpline) { // generate the spline as defined in the SplineSeries object\n\n pathToPoint = series.getPointSpline(points, point, i);\n\n } else if (step) {\n\n if (step === 1) { // right\n pathToPoint = [\n 'L',\n lastPoint.plotX,\n plotY\n ];\n\n } else if (step === 2) { // center\n pathToPoint = [\n 'L',\n (lastPoint.plotX + plotX) / 2,\n lastPoint.plotY,\n 'L',\n (lastPoint.plotX + plotX) / 2,\n plotY\n ];\n\n } else {\n pathToPoint = [\n 'L',\n plotX,\n lastPoint.plotY\n ];\n }\n pathToPoint.push('L', plotX, plotY);\n\n } else {\n // normal line to next point\n pathToPoint = [\n 'L',\n plotX,\n plotY\n ];\n }\n\n // Prepare for animation. When step is enabled, there are two path nodes for each x value.\n xMap.push(point.x);\n if (step) {\n xMap.push(point.x);\n }\n\n graphPath.push.apply(graphPath, pathToPoint);\n gap = false;\n }\n });\n\n graphPath.xMap = xMap;\n series.graphPath = graphPath;\n\n return graphPath;\n\n },\n\n /**\n * Draw the actual graph\n */\n drawGraph: function() {\n var series = this,\n options = this.options,\n graphPath = (this.gappedPath || this.getGraphPath).call(this),\n props = [\n [\n 'graph',\n 'highcharts-graph',\n\n options.lineColor || this.color,\n options.dashStyle\n\n ]\n ];\n\n // Add the zone properties if any\n each(this.zones, function(zone, i) {\n props.push([\n 'zone-graph-' + i,\n 'highcharts-graph highcharts-zone-graph-' + i + ' ' + (zone.className || ''),\n\n zone.color || series.color,\n zone.dashStyle || options.dashStyle\n\n ]);\n });\n\n // Draw the graph\n each(props, function(prop, i) {\n var graphKey = prop[0],\n graph = series[graphKey],\n attribs;\n\n if (graph) {\n graph.endX = graphPath.xMap;\n graph.animate({\n d: graphPath\n });\n\n } else if (graphPath.length) { // #1487\n\n series[graphKey] = series.chart.renderer.path(graphPath)\n .addClass(prop[1])\n .attr({\n zIndex: 1\n }) // #1069\n .add(series.group);\n\n\n attribs = {\n 'stroke': prop[2],\n 'stroke-width': options.lineWidth,\n 'fill': (series.fillGraph && series.color) || 'none' // Polygon series use filled graph\n };\n\n if (prop[3]) {\n attribs.dashstyle = prop[3];\n } else if (options.linecap !== 'square') {\n attribs['stroke-linecap'] = attribs['stroke-linejoin'] = 'round';\n }\n\n graph = series[graphKey]\n .attr(attribs)\n .shadow((i < 2) && options.shadow); // add shadow to normal series (0) or to first zone (1) #3932\n\n }\n\n // Helpers for animation\n if (graph) {\n graph.startX = graphPath.xMap;\n //graph.shiftUnit = options.step ? 2 : 1;\n graph.isArea = graphPath.isArea; // For arearange animation\n }\n });\n },\n\n /**\n * Clip the graphs into the positive and negative coloured graphs\n */\n applyZones: function() {\n var series = this,\n chart = this.chart,\n renderer = chart.renderer,\n zones = this.zones,\n translatedFrom,\n translatedTo,\n clips = this.clips || [],\n clipAttr,\n graph = this.graph,\n area = this.area,\n chartSizeMax = Math.max(chart.chartWidth, chart.chartHeight),\n axis = this[(this.zoneAxis || 'y') + 'Axis'],\n extremes,\n reversed,\n inverted = chart.inverted,\n horiz,\n pxRange,\n pxPosMin,\n pxPosMax,\n ignoreZones = false;\n\n if (zones.length && (graph || area) && axis && axis.min !== undefined) {\n reversed = axis.reversed;\n horiz = axis.horiz;\n // The use of the Color Threshold assumes there are no gaps\n // so it is safe to hide the original graph and area\n if (graph) {\n graph.hide();\n }\n if (area) {\n area.hide();\n }\n\n // Create the clips\n extremes = axis.getExtremes();\n each(zones, function(threshold, i) {\n\n translatedFrom = reversed ?\n (horiz ? chart.plotWidth : 0) :\n (horiz ? 0 : axis.toPixels(extremes.min));\n translatedFrom = Math.min(Math.max(pick(translatedTo, translatedFrom), 0), chartSizeMax);\n translatedTo = Math.min(Math.max(Math.round(axis.toPixels(pick(threshold.value, extremes.max), true)), 0), chartSizeMax);\n\n if (ignoreZones) {\n translatedFrom = translatedTo = axis.toPixels(extremes.max);\n }\n\n pxRange = Math.abs(translatedFrom - translatedTo);\n pxPosMin = Math.min(translatedFrom, translatedTo);\n pxPosMax = Math.max(translatedFrom, translatedTo);\n if (axis.isXAxis) {\n clipAttr = {\n x: inverted ? pxPosMax : pxPosMin,\n y: 0,\n width: pxRange,\n height: chartSizeMax\n };\n if (!horiz) {\n clipAttr.x = chart.plotHeight - clipAttr.x;\n }\n } else {\n clipAttr = {\n x: 0,\n y: inverted ? pxPosMax : pxPosMin,\n width: chartSizeMax,\n height: pxRange\n };\n if (horiz) {\n clipAttr.y = chart.plotWidth - clipAttr.y;\n }\n }\n\n\n /// VML SUPPPORT\n if (inverted && renderer.isVML) {\n if (axis.isXAxis) {\n clipAttr = {\n x: 0,\n y: reversed ? pxPosMin : pxPosMax,\n height: clipAttr.width,\n width: chart.chartWidth\n };\n } else {\n clipAttr = {\n x: clipAttr.y - chart.plotLeft - chart.spacingBox.x,\n y: 0,\n width: clipAttr.height,\n height: chart.chartHeight\n };\n }\n }\n /// END OF VML SUPPORT\n\n\n if (clips[i]) {\n clips[i].animate(clipAttr);\n } else {\n clips[i] = renderer.clipRect(clipAttr);\n\n if (graph) {\n series['zone-graph-' + i].clip(clips[i]);\n }\n\n if (area) {\n series['zone-area-' + i].clip(clips[i]);\n }\n }\n // if this zone extends out of the axis, ignore the others\n ignoreZones = threshold.value > extremes.max;\n });\n this.clips = clips;\n }\n },\n\n /**\n * Initialize and perform group inversion on series.group and series.markerGroup\n */\n invertGroups: function(inverted) {\n var series = this,\n chart = series.chart,\n remover;\n\n function setInvert() {\n each(['group', 'markerGroup'], function(groupName) {\n if (series[groupName]) {\n\n // VML/HTML needs explicit attributes for flipping\n if (chart.renderer.isVML) {\n series[groupName].attr({\n width: series.yAxis.len,\n height: series.xAxis.len\n });\n }\n\n series[groupName].width = series.yAxis.len;\n series[groupName].height = series.xAxis.len;\n series[groupName].invert(inverted);\n }\n });\n }\n\n // Pie, go away (#1736)\n if (!series.xAxis) {\n return;\n }\n\n // A fixed size is needed for inversion to work\n remover = addEvent(chart, 'resize', setInvert);\n addEvent(series, 'destroy', remover);\n\n // Do it now\n setInvert(inverted); // do it now\n\n // On subsequent render and redraw, just do setInvert without setting up events again\n series.invertGroups = setInvert;\n },\n\n /**\n * General abstraction for creating plot groups like series.group,\n * series.dataLabelsGroup and series.markerGroup. On subsequent calls, the\n * group will only be adjusted to the updated plot size.\n */\n plotGroup: function(prop, name, visibility, zIndex, parent) {\n var group = this[prop],\n isNew = !group;\n\n // Generate it on first call\n if (isNew) {\n this[prop] = group = this.chart.renderer.g()\n .attr({\n zIndex: zIndex || 0.1 // IE8 and pointer logic use this\n })\n .add(parent);\n\n }\n\n // Add the class names, and replace existing ones as response to\n // Series.update (#6660)\n group.addClass(\n (\n 'highcharts-' + name +\n ' highcharts-series-' + this.index +\n ' highcharts-' + this.type + '-series ' +\n 'highcharts-color-' + this.colorIndex + ' ' +\n (this.options.className || '')\n ),\n true\n );\n\n // Place it on first and subsequent (redraw) calls\n group.attr({\n visibility: visibility\n })[isNew ? 'attr' : 'animate'](\n this.getPlotBox()\n );\n return group;\n },\n\n /**\n * Get the translation and scale for the plot area of this series\n */\n getPlotBox: function() {\n var chart = this.chart,\n xAxis = this.xAxis,\n yAxis = this.yAxis;\n\n // Swap axes for inverted (#2339)\n if (chart.inverted) {\n xAxis = yAxis;\n yAxis = this.xAxis;\n }\n return {\n translateX: xAxis ? xAxis.left : chart.plotLeft,\n translateY: yAxis ? yAxis.top : chart.plotTop,\n scaleX: 1, // #1623\n scaleY: 1\n };\n },\n\n /**\n * Render the graph and markers\n */\n render: function() {\n var series = this,\n chart = series.chart,\n group,\n options = series.options,\n // Animation doesn't work in IE8 quirks when the group div is\n // hidden, and looks bad in other oldIE\n animDuration = (!!series.animate &&\n chart.renderer.isSVG &&\n animObject(options.animation).duration\n ),\n visibility = series.visible ? 'inherit' : 'hidden', // #2597\n zIndex = options.zIndex,\n hasRendered = series.hasRendered,\n chartSeriesGroup = chart.seriesGroup,\n inverted = chart.inverted;\n\n // the group\n group = series.plotGroup(\n 'group',\n 'series',\n visibility,\n zIndex,\n chartSeriesGroup\n );\n\n series.markerGroup = series.plotGroup(\n 'markerGroup',\n 'markers',\n visibility,\n zIndex,\n chartSeriesGroup\n );\n\n // initiate the animation\n if (animDuration) {\n series.animate(true);\n }\n\n // SVGRenderer needs to know this before drawing elements (#1089, #1795)\n group.inverted = series.isCartesian ? inverted : false;\n\n // draw the graph if any\n if (series.drawGraph) {\n series.drawGraph();\n series.applyZones();\n }\n\n /* each(series.points, function (point) {\n if (point.redraw) {\n point.redraw();\n }\n });*/\n\n // draw the data labels (inn pies they go before the points)\n if (series.drawDataLabels) {\n series.drawDataLabels();\n }\n\n // draw the points\n if (series.visible) {\n series.drawPoints();\n }\n\n\n // draw the mouse tracking area\n if (\n series.drawTracker &&\n series.options.enableMouseTracking !== false\n ) {\n series.drawTracker();\n }\n\n // Handle inverted series and tracker groups\n series.invertGroups(inverted);\n\n // Initial clipping, must be defined after inverting groups for VML.\n // Applies to columns etc. (#3839).\n if (options.clip !== false && !series.sharedClipKey && !hasRendered) {\n group.clip(chart.clipRect);\n }\n\n // Run the animation\n if (animDuration) {\n series.animate();\n }\n\n // Call the afterAnimate function on animation complete (but don't\n // overwrite the animation.complete option which should be available to\n // the user).\n if (!hasRendered) {\n series.animationTimeout = syncTimeout(function() {\n series.afterAnimate();\n }, animDuration);\n }\n\n series.isDirty = false; // means data is in accordance with what you see\n // (See #322) series.isDirty = series.isDirtyData = false; // means\n // data is in accordance with what you see\n series.hasRendered = true;\n },\n\n /**\n * Redraw the series after an update in the axes.\n */\n redraw: function() {\n var series = this,\n chart = series.chart,\n // cache it here as it is set to false in render, but used after\n wasDirty = series.isDirty || series.isDirtyData,\n group = series.group,\n xAxis = series.xAxis,\n yAxis = series.yAxis;\n\n // reposition on resize\n if (group) {\n if (chart.inverted) {\n group.attr({\n width: chart.plotWidth,\n height: chart.plotHeight\n });\n }\n\n group.animate({\n translateX: pick(xAxis && xAxis.left, chart.plotLeft),\n translateY: pick(yAxis && yAxis.top, chart.plotTop)\n });\n }\n\n series.translate();\n series.render();\n if (wasDirty) { // #3868, #3945\n delete this.kdTree;\n }\n },\n\n /**\n * KD Tree && PointSearching Implementation\n */\n\n kdAxisArray: ['clientX', 'plotY'],\n\n searchPoint: function(e, compareX) {\n var series = this,\n xAxis = series.xAxis,\n yAxis = series.yAxis,\n inverted = series.chart.inverted;\n\n return this.searchKDTree({\n clientX: inverted ?\n xAxis.len - e.chartY + xAxis.pos : e.chartX - xAxis.pos,\n plotY: inverted ?\n yAxis.len - e.chartX + yAxis.pos : e.chartY - yAxis.pos\n }, compareX);\n },\n\n /**\n * Build the k-d-tree that is used by mouse and touch interaction to get the\n * closest point. Line-like series typically have a one-dimensional tree \n * where points are searched along the X axis, while scatter-like series\n * typically search in two dimensions, X and Y.\n */\n buildKDTree: function() {\n\n // Prevent multiple k-d-trees from being built simultaneously (#6235)\n this.buildingKdTree = true;\n\n var series = this,\n dimensions = series.options.findNearestPointBy.indexOf('y') > -1 ?\n 2 : 1;\n\n // Internal function\n function _kdtree(points, depth, dimensions) {\n var axis,\n median,\n length = points && points.length;\n\n if (length) {\n\n // alternate between the axis\n axis = series.kdAxisArray[depth % dimensions];\n\n // sort point array\n points.sort(function(a, b) {\n return a[axis] - b[axis];\n });\n\n median = Math.floor(length / 2);\n\n // build and return nod\n return {\n point: points[median],\n left: _kdtree(\n points.slice(0, median), depth + 1, dimensions\n ),\n right: _kdtree(\n points.slice(median + 1), depth + 1, dimensions\n )\n };\n\n }\n }\n\n // Start the recursive build process with a clone of the points array\n // and null points filtered out (#3873)\n function startRecursive() {\n series.kdTree = _kdtree(\n series.getValidPoints(\n null,\n // For line-type series restrict to plot area, but\n // column-type series not (#3916, #4511)\n !series.directTouch\n ),\n dimensions,\n dimensions\n );\n series.buildingKdTree = false;\n }\n delete series.kdTree;\n\n // For testing tooltips, don't build async\n syncTimeout(startRecursive, series.options.kdNow ? 0 : 1);\n },\n\n searchKDTree: function(point, compareX) {\n var series = this,\n kdX = this.kdAxisArray[0],\n kdY = this.kdAxisArray[1],\n kdComparer = compareX ? 'distX' : 'dist',\n kdDimensions = series.options.findNearestPointBy.indexOf('y') > -1 ?\n 2 : 1;\n\n // Set the one and two dimensional distance on the point object\n function setDistance(p1, p2) {\n var x = (defined(p1[kdX]) && defined(p2[kdX])) ?\n Math.pow(p1[kdX] - p2[kdX], 2) :\n null,\n y = (defined(p1[kdY]) && defined(p2[kdY])) ?\n Math.pow(p1[kdY] - p2[kdY], 2) :\n null,\n r = (x || 0) + (y || 0);\n\n p2.dist = defined(r) ? Math.sqrt(r) : Number.MAX_VALUE;\n p2.distX = defined(x) ? Math.sqrt(x) : Number.MAX_VALUE;\n }\n\n function _search(search, tree, depth, dimensions) {\n var point = tree.point,\n axis = series.kdAxisArray[depth % dimensions],\n tdist,\n sideA,\n sideB,\n ret = point,\n nPoint1,\n nPoint2;\n\n setDistance(search, point);\n\n // Pick side based on distance to splitting point\n tdist = search[axis] - point[axis];\n sideA = tdist < 0 ? 'left' : 'right';\n sideB = tdist < 0 ? 'right' : 'left';\n\n // End of tree\n if (tree[sideA]) {\n nPoint1 = _search(search, tree[sideA], depth + 1, dimensions);\n\n ret = (nPoint1[kdComparer] < ret[kdComparer] ? nPoint1 : point);\n }\n if (tree[sideB]) {\n // compare distance to current best to splitting point to decide\n // wether to check side B or not\n if (Math.sqrt(tdist * tdist) < ret[kdComparer]) {\n nPoint2 = _search(\n search,\n tree[sideB],\n depth + 1,\n dimensions\n );\n ret = nPoint2[kdComparer] < ret[kdComparer] ?\n nPoint2 :\n ret;\n }\n }\n\n return ret;\n }\n\n if (!this.kdTree && !this.buildingKdTree) {\n this.buildKDTree();\n }\n\n if (this.kdTree) {\n return _search(point, this.kdTree, kdDimensions, kdDimensions);\n }\n }\n\n }); // end Series prototype\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var Axis = H.Axis,\n Chart = H.Chart,\n correctFloat = H.correctFloat,\n defined = H.defined,\n destroyObjectProperties = H.destroyObjectProperties,\n each = H.each,\n format = H.format,\n objectEach = H.objectEach,\n pick = H.pick,\n Series = H.Series;\n\n /**\n * The class for stacks. Each stack, on a specific X value and either negative\n * or positive, has its own stack item.\n *\n * @class\n */\n function StackItem(axis, options, isNegative, x, stackOption) {\n\n var inverted = axis.chart.inverted;\n\n this.axis = axis;\n\n // Tells if the stack is negative\n this.isNegative = isNegative;\n\n // Save the options to be able to style the label\n this.options = options;\n\n // Save the x value to be able to position the label later\n this.x = x;\n\n // Initialize total value\n this.total = null;\n\n // This will keep each points' extremes stored by series.index and point \n // index\n this.points = {};\n\n // Save the stack option on the series configuration object, and whether to \n // treat it as percent\n this.stack = stackOption;\n this.leftCliff = 0;\n this.rightCliff = 0;\n\n // The align options and text align varies on whether the stack is negative \n // and if the chart is inverted or not.\n // First test the user supplied value, then use the dynamic.\n this.alignOptions = {\n align: options.align ||\n (inverted ? (isNegative ? 'left' : 'right') : 'center'),\n verticalAlign: options.verticalAlign ||\n (inverted ? 'middle' : (isNegative ? 'bottom' : 'top')),\n y: pick(options.y, inverted ? 4 : (isNegative ? 14 : -6)),\n x: pick(options.x, inverted ? (isNegative ? -6 : 6) : 0)\n };\n\n this.textAlign = options.textAlign ||\n (inverted ? (isNegative ? 'right' : 'left') : 'center');\n }\n\n StackItem.prototype = {\n destroy: function() {\n destroyObjectProperties(this, this.axis);\n },\n\n /**\n * Renders the stack total label and adds it to the stack label group.\n */\n render: function(group) {\n var options = this.options,\n formatOption = options.format,\n str = formatOption ?\n format(formatOption, this) :\n options.formatter.call(this); // format the text in the label\n\n // Change the text to reflect the new total and set visibility to hidden\n // in case the serie is hidden\n if (this.label) {\n this.label.attr({\n text: str,\n visibility: 'hidden'\n });\n // Create new label\n } else {\n this.label =\n this.axis.chart.renderer.text(str, null, null, options.useHTML)\n .css(options.style)\n .attr({\n align: this.textAlign,\n rotation: options.rotation,\n visibility: 'hidden' // hidden until setOffset is called\n })\n .add(group); // add to the labels-group\n }\n },\n\n /**\n * Sets the offset that the stack has from the x value and repositions the\n * label.\n */\n setOffset: function(xOffset, xWidth) {\n var stackItem = this,\n axis = stackItem.axis,\n chart = axis.chart,\n inverted = chart.inverted,\n reversed = axis.reversed,\n neg = (this.isNegative && !reversed) ||\n (!this.isNegative && reversed), // #4056\n // stack value translated mapped to chart coordinates\n y = axis.translate(\n axis.usePercentage ? 100 : this.total,\n 0,\n 0,\n 0,\n 1\n ),\n yZero = axis.translate(0), // stack origin\n h = Math.abs(y - yZero), // stack height\n x = chart.xAxis[0].translate(this.x) + xOffset, // stack x position\n plotHeight = chart.plotHeight,\n stackBox = { // this is the box for the complete stack\n x: inverted ? (neg ? y : y - h) : x,\n y: inverted ?\n plotHeight - x - xWidth : (neg ? (plotHeight - y - h) :\n plotHeight - y),\n width: inverted ? h : xWidth,\n height: inverted ? xWidth : h\n },\n label = this.label,\n alignAttr;\n\n if (label) {\n // Align the label to the box\n label.align(this.alignOptions, null, stackBox);\n\n // Set visibility (#678)\n alignAttr = label.alignAttr;\n label[\n this.options.crop === false || chart.isInsidePlot(\n alignAttr.x,\n alignAttr.y\n ) ? 'show' : 'hide'](true);\n }\n }\n };\n\n /**\n * Generate stacks for each series and calculate stacks total values\n */\n Chart.prototype.getStacks = function() {\n var chart = this;\n\n // reset stacks for each yAxis\n each(chart.yAxis, function(axis) {\n if (axis.stacks && axis.hasVisibleSeries) {\n axis.oldStacks = axis.stacks;\n }\n });\n\n each(chart.series, function(series) {\n if (series.options.stacking && (series.visible === true ||\n chart.options.chart.ignoreHiddenSeries === false)) {\n series.stackKey = series.type + pick(series.options.stack, '');\n }\n });\n };\n\n\n // Stacking methods defined on the Axis prototype\n\n /**\n * Build the stacks from top down\n */\n Axis.prototype.buildStacks = function() {\n var axisSeries = this.series,\n series,\n reversedStacks = pick(this.options.reversedStacks, true),\n len = axisSeries.length,\n i;\n if (!this.isXAxis) {\n this.usePercentage = false;\n i = len;\n while (i--) {\n axisSeries[reversedStacks ? i : len - i - 1].setStackedPoints();\n }\n\n i = len;\n while (i--) {\n series = axisSeries[reversedStacks ? i : len - i - 1];\n if (series.setStackCliffs) {\n series.setStackCliffs();\n }\n }\n // Loop up again to compute percent stack\n if (this.usePercentage) {\n for (i = 0; i < len; i++) {\n axisSeries[i].setPercentStacks();\n }\n }\n }\n };\n\n Axis.prototype.renderStackTotals = function() {\n var axis = this,\n chart = axis.chart,\n renderer = chart.renderer,\n stacks = axis.stacks,\n stackTotalGroup = axis.stackTotalGroup;\n\n // Create a separate group for the stack total labels\n if (!stackTotalGroup) {\n axis.stackTotalGroup = stackTotalGroup =\n renderer.g('stack-labels')\n .attr({\n visibility: 'visible',\n zIndex: 6\n })\n .add();\n }\n\n // plotLeft/Top will change when y axis gets wider so we need to translate\n // the stackTotalGroup at every render call. See bug #506 and #516\n stackTotalGroup.translate(chart.plotLeft, chart.plotTop);\n\n // Render each stack total\n objectEach(stacks, function(type) {\n objectEach(type, function(stack) {\n stack.render(stackTotalGroup);\n });\n });\n };\n\n /**\n * Set all the stacks to initial states and destroy unused ones.\n */\n Axis.prototype.resetStacks = function() {\n var axis = this,\n stacks = axis.stacks;\n if (!axis.isXAxis) {\n objectEach(stacks, function(type) {\n objectEach(type, function(stack, key) {\n // Clean up memory after point deletion (#1044, #4320)\n if (stack.touched < axis.stacksTouched) {\n stack.destroy();\n delete type[key];\n\n // Reset stacks\n } else {\n stack.total = null;\n stack.cum = null;\n }\n });\n });\n }\n };\n\n Axis.prototype.cleanStacks = function() {\n var stacks;\n\n if (!this.isXAxis) {\n if (this.oldStacks) {\n stacks = this.stacks = this.oldStacks;\n }\n\n // reset stacks\n objectEach(stacks, function(type) {\n objectEach(type, function(stack) {\n stack.cum = stack.total;\n });\n });\n }\n };\n\n\n // Stacking methods defnied for Series prototype\n\n /**\n * Adds series' points value to corresponding stack\n */\n Series.prototype.setStackedPoints = function() {\n if (!this.options.stacking || (this.visible !== true &&\n this.chart.options.chart.ignoreHiddenSeries !== false)) {\n return;\n }\n\n var series = this,\n xData = series.processedXData,\n yData = series.processedYData,\n stackedYData = [],\n yDataLength = yData.length,\n seriesOptions = series.options,\n threshold = seriesOptions.threshold,\n stackThreshold = seriesOptions.startFromThreshold ? threshold : 0,\n stackOption = seriesOptions.stack,\n stacking = seriesOptions.stacking,\n stackKey = series.stackKey,\n negKey = '-' + stackKey,\n negStacks = series.negStacks,\n yAxis = series.yAxis,\n stacks = yAxis.stacks,\n oldStacks = yAxis.oldStacks,\n stackIndicator,\n isNegative,\n stack,\n other,\n key,\n pointKey,\n i,\n x,\n y;\n\n\n yAxis.stacksTouched += 1;\n\n // loop over the non-null y values and read them into a local array\n for (i = 0; i < yDataLength; i++) {\n x = xData[i];\n y = yData[i];\n stackIndicator = series.getStackIndicator(\n stackIndicator,\n x,\n series.index\n );\n pointKey = stackIndicator.key;\n // Read stacked values into a stack based on the x value,\n // the sign of y and the stack key. Stacking is also handled for null\n // values (#739)\n isNegative = negStacks && y < (stackThreshold ? 0 : threshold);\n key = isNegative ? negKey : stackKey;\n\n // Create empty object for this stack if it doesn't exist yet\n if (!stacks[key]) {\n stacks[key] = {};\n }\n\n // Initialize StackItem for this x\n if (!stacks[key][x]) {\n if (oldStacks[key] && oldStacks[key][x]) {\n stacks[key][x] = oldStacks[key][x];\n stacks[key][x].total = null;\n } else {\n stacks[key][x] = new StackItem(\n yAxis,\n yAxis.options.stackLabels,\n isNegative,\n x,\n stackOption\n );\n }\n }\n\n // If the StackItem doesn't exist, create it first\n stack = stacks[key][x];\n if (y !== null) {\n stack.points[pointKey] = stack.points[series.index] = [pick(stack.cum, stackThreshold)];\n\n // Record the base of the stack\n if (!defined(stack.cum)) {\n stack.base = pointKey;\n }\n stack.touched = yAxis.stacksTouched;\n\n\n // In area charts, if there are multiple points on the same X value,\n // let the area fill the full span of those points\n if (stackIndicator.index > 0 && series.singleStacks === false) {\n stack.points[pointKey][0] =\n stack.points[series.index + ',' + x + ',0'][0];\n }\n }\n\n // Add value to the stack total\n if (stacking === 'percent') {\n\n // Percent stacked column, totals are the same for the positive and\n // negative stacks\n other = isNegative ? stackKey : negKey;\n if (negStacks && stacks[other] && stacks[other][x]) {\n other = stacks[other][x];\n stack.total = other.total =\n Math.max(other.total, stack.total) + Math.abs(y) || 0;\n\n // Percent stacked areas\n } else {\n stack.total = correctFloat(stack.total + (Math.abs(y) || 0));\n }\n } else {\n stack.total = correctFloat(stack.total + (y || 0));\n }\n\n stack.cum = pick(stack.cum, stackThreshold) + (y || 0);\n\n if (y !== null) {\n stack.points[pointKey].push(stack.cum);\n stackedYData[i] = stack.cum;\n }\n\n }\n\n if (stacking === 'percent') {\n yAxis.usePercentage = true;\n }\n\n this.stackedYData = stackedYData; // To be used in getExtremes\n\n // Reset old stacks\n yAxis.oldStacks = {};\n };\n\n /**\n * Iterate over all stacks and compute the absolute values to percent\n */\n Series.prototype.setPercentStacks = function() {\n var series = this,\n stackKey = series.stackKey,\n stacks = series.yAxis.stacks,\n processedXData = series.processedXData,\n stackIndicator;\n\n each([stackKey, '-' + stackKey], function(key) {\n var i = processedXData.length,\n x,\n stack,\n pointExtremes,\n totalFactor;\n\n while (i--) {\n x = processedXData[i];\n stackIndicator = series.getStackIndicator(\n stackIndicator,\n x,\n series.index,\n key\n );\n stack = stacks[key] && stacks[key][x];\n pointExtremes = stack && stack.points[stackIndicator.key];\n if (pointExtremes) {\n totalFactor = stack.total ? 100 / stack.total : 0;\n // Y bottom value\n pointExtremes[0] = correctFloat(pointExtremes[0] * totalFactor);\n // Y value\n pointExtremes[1] = correctFloat(pointExtremes[1] * totalFactor);\n series.stackedYData[i] = pointExtremes[1];\n }\n }\n });\n };\n\n /**\n * Get stack indicator, according to it's x-value, to determine points with the\n * same x-value\n */\n Series.prototype.getStackIndicator = function(stackIndicator, x, index, key) {\n // Update stack indicator, when:\n // first point in a stack || x changed || stack type (negative vs positive)\n // changed:\n if (!defined(stackIndicator) || stackIndicator.x !== x ||\n (key && stackIndicator.key !== key)) {\n stackIndicator = {\n x: x,\n index: 0,\n key: key\n };\n } else {\n stackIndicator.index++;\n }\n\n stackIndicator.key = [index, x, stackIndicator.index].join(',');\n\n return stackIndicator;\n };\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var addEvent = H.addEvent,\n animate = H.animate,\n Axis = H.Axis,\n Chart = H.Chart,\n createElement = H.createElement,\n css = H.css,\n defined = H.defined,\n each = H.each,\n erase = H.erase,\n extend = H.extend,\n fireEvent = H.fireEvent,\n inArray = H.inArray,\n isNumber = H.isNumber,\n isObject = H.isObject,\n isArray = H.isArray,\n merge = H.merge,\n objectEach = H.objectEach,\n pick = H.pick,\n Point = H.Point,\n Series = H.Series,\n seriesTypes = H.seriesTypes,\n setAnimation = H.setAnimation,\n splat = H.splat;\n\n // Extend the Chart prototype for dynamic methods\n extend(Chart.prototype, /** @lends Highcharts.Chart.prototype */ {\n\n /**\n * Add a series to the chart after render time. Note that this method should\n * never be used when adding data synchronously at chart render time, as it\n * adds expense to the calculations and rendering. When adding data at the\n * same time as the chart is initiated, add the series as a configuration\n * option instead. With multiple axes, the `offset` is dynamically adjusted.\n *\n * @param {SeriesOptions} options\n * The config options for the series.\n * @param {Boolean} [redraw=true]\n * Whether to redraw the chart after adding.\n * @param {AnimationOptions} animation\n * Whether to apply animation, and optionally animation\n * configuration.\n *\n * @return {Highcharts.Series}\n * The newly created series object.\n *\n * @sample highcharts/members/chart-addseries/\n * Add a series from a button\n * @sample stock/members/chart-addseries/\n * Add a series in Highstock\n */\n addSeries: function(options, redraw, animation) {\n var series,\n chart = this;\n\n if (options) {\n redraw = pick(redraw, true); // defaults to true\n\n fireEvent(chart, 'addSeries', {\n options: options\n }, function() {\n series = chart.initSeries(options);\n\n chart.isDirtyLegend = true; // the series array is out of sync with the display\n chart.linkSeries();\n if (redraw) {\n chart.redraw(animation);\n }\n });\n }\n\n return series;\n },\n\n /**\n * Add an axis to the chart after render time. Note that this method should\n * never be used when adding data synchronously at chart render time, as it\n * adds expense to the calculations and rendering. When adding data at the\n * same time as the chart is initiated, add the axis as a configuration\n * option instead.\n * @param {AxisOptions} options\n * The axis options.\n * @param {Boolean} [isX=false]\n * Whether it is an X axis or a value axis.\n * @param {Boolean} [redraw=true]\n * Whether to redraw the chart after adding.\n * @param {AnimationOptions} [animation=true]\n * Whether and how to apply animation in the redraw.\n *\n * @sample highcharts/members/chart-addaxis/ Add and remove axes\n */\n addAxis: function(options, isX, redraw, animation) {\n var key = isX ? 'xAxis' : 'yAxis',\n chartOptions = this.options,\n userOptions = merge(options, {\n index: this[key].length,\n isX: isX\n });\n\n new Axis(this, userOptions); // eslint-disable-line no-new\n\n // Push the new axis options to the chart options\n chartOptions[key] = splat(chartOptions[key] || {});\n chartOptions[key].push(userOptions);\n\n if (pick(redraw, true)) {\n this.redraw(animation);\n }\n },\n\n /**\n * Dim the chart and show a loading text or symbol. Options for the loading\n * screen are defined in {@link\n * https://api.highcharts.com/highcharts/loading|the loading options}.\n * \n * @param {String} str\n * An optional text to show in the loading label instead of the\n * default one. The default text is set in {@link\n * http://api.highcharts.com/highcharts/lang.loading|lang.loading}.\n *\n * @sample highcharts/members/chart-hideloading/\n * Show and hide loading from a button\n * @sample highcharts/members/chart-showloading/\n * Apply different text labels\n * @sample stock/members/chart-show-hide-loading/\n * Toggle loading in Highstock\n */\n showLoading: function(str) {\n var chart = this,\n options = chart.options,\n loadingDiv = chart.loadingDiv,\n loadingOptions = options.loading,\n setLoadingSize = function() {\n if (loadingDiv) {\n css(loadingDiv, {\n left: chart.plotLeft + 'px',\n top: chart.plotTop + 'px',\n width: chart.plotWidth + 'px',\n height: chart.plotHeight + 'px'\n });\n }\n };\n\n // create the layer at the first call\n if (!loadingDiv) {\n chart.loadingDiv = loadingDiv = createElement('div', {\n className: 'highcharts-loading highcharts-loading-hidden'\n }, null, chart.container);\n\n chart.loadingSpan = createElement(\n 'span', {\n className: 'highcharts-loading-inner'\n },\n null,\n loadingDiv\n );\n addEvent(chart, 'redraw', setLoadingSize); // #1080\n }\n\n loadingDiv.className = 'highcharts-loading';\n\n // Update text\n chart.loadingSpan.innerHTML = str || options.lang.loading;\n\n\n // Update visuals\n css(loadingDiv, extend(loadingOptions.style, {\n zIndex: 10\n }));\n css(chart.loadingSpan, loadingOptions.labelStyle);\n\n // Show it\n if (!chart.loadingShown) {\n css(loadingDiv, {\n opacity: 0,\n display: ''\n });\n animate(loadingDiv, {\n opacity: loadingOptions.style.opacity || 0.5\n }, {\n duration: loadingOptions.showDuration || 0\n });\n }\n\n\n chart.loadingShown = true;\n setLoadingSize();\n },\n\n /**\n * Hide the loading layer.\n *\n * @see Highcharts.Chart#showLoading\n * @sample highcharts/members/chart-hideloading/\n * Show and hide loading from a button\n * @sample stock/members/chart-show-hide-loading/\n * Toggle loading in Highstock\n */\n hideLoading: function() {\n var options = this.options,\n loadingDiv = this.loadingDiv;\n\n if (loadingDiv) {\n loadingDiv.className = 'highcharts-loading highcharts-loading-hidden';\n\n animate(loadingDiv, {\n opacity: 0\n }, {\n duration: options.loading.hideDuration || 100,\n complete: function() {\n css(loadingDiv, {\n display: 'none'\n });\n }\n });\n\n }\n this.loadingShown = false;\n },\n\n /** \n * These properties cause isDirtyBox to be set to true when updating. Can be extended from plugins.\n */\n propsRequireDirtyBox: ['backgroundColor', 'borderColor', 'borderWidth', 'margin', 'marginTop', 'marginRight',\n 'marginBottom', 'marginLeft', 'spacing', 'spacingTop', 'spacingRight', 'spacingBottom', 'spacingLeft',\n 'borderRadius', 'plotBackgroundColor', 'plotBackgroundImage', 'plotBorderColor', 'plotBorderWidth',\n 'plotShadow', 'shadow'\n ],\n\n /** \n * These properties cause all series to be updated when updating. Can be\n * extended from plugins.\n */\n propsRequireUpdateSeries: ['chart.inverted', 'chart.polar',\n 'chart.ignoreHiddenSeries', 'chart.type', 'colors', 'plotOptions',\n 'tooltip'\n ],\n\n /**\n * A generic function to update any element of the chart. Elements can be\n * enabled and disabled, moved, re-styled, re-formatted etc.\n *\n * A special case is configuration objects that take arrays, for example\n * {@link https://api.highcharts.com/highcharts/xAxis|xAxis}, \n * {@link https://api.highcharts.com/highcharts/yAxis|yAxis} or \n * {@link https://api.highcharts.com/highcharts/series|series}. For these\n * collections, an `id` option is used to map the new option set to an\n * existing object. If an existing object of the same id is not found, the\n * corresponding item is updated. So for example, running `chart.update`\n * with a series item without an id, will cause the existing chart's series\n * with the same index in the series array to be updated.\n *\n * See also the {@link https://api.highcharts.com/highcharts/responsive|\n * responsive option set}. Switching between `responsive.rules` basically\n * runs `chart.update` under the hood.\n *\n * @param {Options} options\n * A configuration object for the new chart options.\n * @param {Boolean} [redraw=true]\n * Whether to redraw the chart.\n *\n * @sample highcharts/members/chart-update/\n * Update chart geometry \n */\n update: function(options, redraw) {\n var chart = this,\n adders = {\n credits: 'addCredits',\n title: 'setTitle',\n subtitle: 'setSubtitle'\n },\n optionsChart = options.chart,\n updateAllAxes,\n updateAllSeries,\n newWidth,\n newHeight;\n\n // If the top-level chart option is present, some special updates are required \n if (optionsChart) {\n merge(true, chart.options.chart, optionsChart);\n\n // Setter function\n if ('className' in optionsChart) {\n chart.setClassName(optionsChart.className);\n }\n\n if ('inverted' in optionsChart || 'polar' in optionsChart) {\n // Parse options.chart.inverted and options.chart.polar together\n // with the available series.\n chart.propFromSeries();\n updateAllAxes = true;\n }\n\n if ('alignTicks' in optionsChart) { // #6452\n updateAllAxes = true;\n }\n\n objectEach(optionsChart, function(val, key) {\n if (inArray('chart.' + key, chart.propsRequireUpdateSeries) !== -1) {\n updateAllSeries = true;\n }\n // Only dirty box\n if (inArray(key, chart.propsRequireDirtyBox) !== -1) {\n chart.isDirtyBox = true;\n }\n });\n\n\n if ('style' in optionsChart) {\n chart.renderer.setStyle(optionsChart.style);\n }\n\n }\n\n // Moved up, because tooltip needs updated plotOptions (#6218)\n\n if (options.colors) {\n this.options.colors = options.colors;\n }\n\n\n if (options.plotOptions) {\n merge(true, this.options.plotOptions, options.plotOptions);\n }\n\n // Some option stuctures correspond one-to-one to chart objects that\n // have update methods, for example\n // options.credits => chart.credits\n // options.legend => chart.legend\n // options.title => chart.title\n // options.tooltip => chart.tooltip\n // options.subtitle => chart.subtitle\n // options.mapNavigation => chart.mapNavigation\n // options.navigator => chart.navigator\n // options.scrollbar => chart.scrollbar\n objectEach(options, function(val, key) {\n if (chart[key] && typeof chart[key].update === 'function') {\n chart[key].update(val, false);\n\n // If a one-to-one object does not exist, look for an adder function\n } else if (typeof chart[adders[key]] === 'function') {\n chart[adders[key]](val);\n }\n\n if (\n key !== 'chart' &&\n inArray(key, chart.propsRequireUpdateSeries) !== -1\n ) {\n updateAllSeries = true;\n }\n });\n\n // Setters for collections. For axes and series, each item is referred\n // by an id. If the id is not found, it defaults to the corresponding\n // item in the collection, so setting one series without an id, will\n // update the first series in the chart. Setting two series without\n // an id will update the first and the second respectively (#6019)\n // chart.update and responsive.\n each([\n 'xAxis',\n 'yAxis',\n 'zAxis',\n 'series',\n 'colorAxis',\n 'pane'\n ], function(coll) {\n if (options[coll]) {\n each(splat(options[coll]), function(newOptions, i) {\n var item = (\n defined(newOptions.id) &&\n chart.get(newOptions.id)\n ) || chart[coll][i];\n if (item && item.coll === coll) {\n item.update(newOptions, false);\n }\n });\n }\n });\n\n if (updateAllAxes) {\n each(chart.axes, function(axis) {\n axis.update({}, false);\n });\n }\n\n // Certain options require the whole series structure to be thrown away\n // and rebuilt\n if (updateAllSeries) {\n each(chart.series, function(series) {\n series.update({}, false);\n });\n }\n\n // For loading, just update the options, do not redraw\n if (options.loading) {\n merge(true, chart.options.loading, options.loading);\n }\n\n // Update size. Redraw is forced.\n newWidth = optionsChart && optionsChart.width;\n newHeight = optionsChart && optionsChart.height;\n if ((isNumber(newWidth) && newWidth !== chart.chartWidth) ||\n (isNumber(newHeight) && newHeight !== chart.chartHeight)) {\n chart.setSize(newWidth, newHeight);\n } else if (pick(redraw, true)) {\n chart.redraw();\n }\n },\n\n /**\n * Setter function to allow use from chart.update\n */\n setSubtitle: function(options) {\n this.setTitle(undefined, options);\n }\n\n\n });\n\n // extend the Point prototype for dynamic methods\n extend(Point.prototype, /** @lends Highcharts.Point.prototype */ {\n /**\n * Update point with new options (typically x/y data) and optionally redraw\n * the series.\n *\n * @param {Object} options\n * The point options. Point options are handled as described under\n * the `series.data` item for each series type. For example\n * for a line series, if options is a single number, the point will\n * be given that number as the main y value. If it is an array, it\n * will be interpreted as x and y values respectively. If it is an\n * object, advanced options are applied. \n * @param {Boolean} [redraw=true]\n * Whether to redraw the chart after the point is updated. If doing\n * more operations on the chart, it is best practice to set\n * `redraw` to false and call `chart.redraw()` after.\n * @param {AnimationOptions} [animation=true]\n * Whether to apply animation, and optionally animation\n * configuration.\n *\n * @sample highcharts/members/point-update-column/\n * Update column value\n * @sample highcharts/members/point-update-pie/\n * Update pie slice\n * @sample maps/members/point-update/\n * Update map area value in Highmaps\n */\n update: function(options, redraw, animation, runEvent) {\n var point = this,\n series = point.series,\n graphic = point.graphic,\n i,\n chart = series.chart,\n seriesOptions = series.options;\n\n redraw = pick(redraw, true);\n\n function update() {\n\n point.applyOptions(options);\n\n // Update visuals\n if (point.y === null && graphic) { // #4146\n point.graphic = graphic.destroy();\n }\n if (isObject(options, true)) {\n // Destroy so we can get new elements\n if (graphic && graphic.element) {\n if (options && options.marker && options.marker.symbol) {\n point.graphic = graphic.destroy();\n }\n }\n if (options && options.dataLabels && point.dataLabel) { // #2468\n point.dataLabel = point.dataLabel.destroy();\n }\n }\n\n // record changes in the parallel arrays\n i = point.index;\n series.updateParallelArrays(point, i);\n\n // Record the options to options.data. If the old or the new config\n // is an object, use point options, otherwise use raw options\n // (#4701, #4916).\n seriesOptions.data[i] = (\n isObject(seriesOptions.data[i], true) ||\n isObject(options, true)\n ) ?\n point.options :\n options;\n\n // redraw\n series.isDirty = series.isDirtyData = true;\n if (!series.fixedBox && series.hasCartesianSeries) { // #1906, #2320\n chart.isDirtyBox = true;\n }\n\n if (seriesOptions.legendType === 'point') { // #1831, #1885\n chart.isDirtyLegend = true;\n }\n if (redraw) {\n chart.redraw(animation);\n }\n }\n\n // Fire the event with a default handler of doing the update\n if (runEvent === false) { // When called from setData\n update();\n } else {\n point.firePointEvent('update', {\n options: options\n }, update);\n }\n },\n\n /**\n * Remove a point and optionally redraw the series and if necessary the axes\n * @param {Boolean} redraw\n * Whether to redraw the chart or wait for an explicit call. When\n * doing more operations on the chart, for example running\n * `point.remove()` in a loop, it is best practice to set `redraw`\n * to false and call `chart.redraw()` after. \n * @param {AnimationOptions} [animation=false]\n * Whether to apply animation, and optionally animation\n * configuration.\n *\n * @sample highcharts/plotoptions/series-point-events-remove/\n * Remove point and confirm\n * @sample highcharts/members/point-remove/\n * Remove pie slice\n * @sample maps/members/point-remove/\n * Remove selected points in Highmaps\n */\n remove: function(redraw, animation) {\n this.series.removePoint(inArray(this, this.series.data), redraw, animation);\n }\n });\n\n // Extend the series prototype for dynamic methods\n extend(Series.prototype, /** @lends Series.prototype */ {\n /**\n * Add a point to the series after render time. The point can be added at\n * the end, or by giving it an X value, to the start or in the middle of the\n * series.\n * \n * @param {Number|Array|Object} options\n * The point options. If options is a single number, a point with\n * that y value is appended to the series.If it is an array, it will\n * be interpreted as x and y values respectively. If it is an\n * object, advanced options as outlined under `series.data` are\n * applied.\n * @param {Boolean} [redraw=true]\n * Whether to redraw the chart after the point is added. When adding\n * more than one point, it is highly recommended that the redraw\n * option be set to false, and instead {@link Chart#redraw}\n * is explicitly called after the adding of points is finished.\n * Otherwise, the chart will redraw after adding each point.\n * @param {Boolean} [shift=false]\n * If true, a point is shifted off the start of the series as one is\n * appended to the end.\n * @param {AnimationOptions} [animation]\n * Whether to apply animation, and optionally animation\n * configuration.\n *\n * @sample highcharts/members/series-addpoint-append/\n * Append point\n * @sample highcharts/members/series-addpoint-append-and-shift/\n * Append and shift\n * @sample highcharts/members/series-addpoint-x-and-y/\n * Both X and Y values given\n * @sample highcharts/members/series-addpoint-pie/\n * Append pie slice\n * @sample stock/members/series-addpoint/\n * Append 100 points in Highstock\n * @sample stock/members/series-addpoint-shift/\n * Append and shift in Highstock\n * @sample maps/members/series-addpoint/\n * Add a point in Highmaps\n */\n addPoint: function(options, redraw, shift, animation) {\n var series = this,\n seriesOptions = series.options,\n data = series.data,\n chart = series.chart,\n xAxis = series.xAxis,\n names = xAxis && xAxis.hasNames && xAxis.names,\n dataOptions = seriesOptions.data,\n point,\n isInTheMiddle,\n xData = series.xData,\n i,\n x;\n\n // Optional redraw, defaults to true\n redraw = pick(redraw, true);\n\n // Get options and push the point to xData, yData and series.options. In series.generatePoints\n // the Point instance will be created on demand and pushed to the series.data array.\n point = {\n series: series\n };\n series.pointClass.prototype.applyOptions.apply(point, [options]);\n x = point.x;\n\n // Get the insertion point\n i = xData.length;\n if (series.requireSorting && x < xData[i - 1]) {\n isInTheMiddle = true;\n while (i && xData[i - 1] > x) {\n i--;\n }\n }\n\n series.updateParallelArrays(point, 'splice', i, 0, 0); // insert undefined item\n series.updateParallelArrays(point, i); // update it\n\n if (names && point.name) {\n names[x] = point.name;\n }\n dataOptions.splice(i, 0, options);\n\n if (isInTheMiddle) {\n series.data.splice(i, 0, null);\n series.processData();\n }\n\n // Generate points to be added to the legend (#1329)\n if (seriesOptions.legendType === 'point') {\n series.generatePoints();\n }\n\n // Shift the first point off the parallel arrays\n if (shift) {\n if (data[0] && data[0].remove) {\n data[0].remove(false);\n } else {\n data.shift();\n series.updateParallelArrays(point, 'shift');\n\n dataOptions.shift();\n }\n }\n\n // redraw\n series.isDirty = true;\n series.isDirtyData = true;\n\n if (redraw) {\n chart.redraw(animation); // Animation is set anyway on redraw, #5665\n }\n },\n\n /**\n * Remove a point from the series. Unlike the {@link Highcharts.Point#remove}\n * method, this can also be done on a point that is not instanciated because\n * it is outside the view or subject to Highstock data grouping.\n *\n * @param {Number} i\n * The index of the point in the {@link Highcharts.Series.data|data}\n * array.\n * @param {Boolean} [redraw=true]\n * Whether to redraw the chart after the point is added. When \n * removing more than one point, it is highly recommended that the\n * `redraw` option be set to `false`, and instead {@link\n * Highcharts.Chart#redraw} is explicitly called after the adding of\n * points is finished.\n * @param {AnimationOptions} [animation]\n * Whether and optionally how the series should be animated.\n *\n * @sample highcharts/members/series-removepoint/\n * Remove cropped point\n */\n removePoint: function(i, redraw, animation) {\n\n var series = this,\n data = series.data,\n point = data[i],\n points = series.points,\n chart = series.chart,\n remove = function() {\n\n if (points && points.length === data.length) { // #4935\n points.splice(i, 1);\n }\n data.splice(i, 1);\n series.options.data.splice(i, 1);\n series.updateParallelArrays(point || {\n series: series\n }, 'splice', i, 1);\n\n if (point) {\n point.destroy();\n }\n\n // redraw\n series.isDirty = true;\n series.isDirtyData = true;\n if (redraw) {\n chart.redraw();\n }\n };\n\n setAnimation(animation, chart);\n redraw = pick(redraw, true);\n\n // Fire the event with a default handler of removing the point\n if (point) {\n point.firePointEvent('remove', null, remove);\n } else {\n remove();\n }\n },\n\n /**\n * Remove a series and optionally redraw the chart.\n *\n * @param {Boolean} [redraw=true]\n * Whether to redraw the chart or wait for an explicit call to\n * {@link Highcharts.Chart#redraw}.\n * @param {AnimationOptions} [animation]\n * Whether to apply animation, and optionally animation\n * configuration\n * @param {Boolean} [withEvent=true]\n * Used internally, whether to fire the series `remove` event.\n *\n * @sample highcharts/members/series-remove/\n * Remove first series from a button\n */\n remove: function(redraw, animation, withEvent) {\n var series = this,\n chart = series.chart;\n\n function remove() {\n\n // Destroy elements\n series.destroy();\n\n // Redraw\n chart.isDirtyLegend = chart.isDirtyBox = true;\n chart.linkSeries();\n\n if (pick(redraw, true)) {\n chart.redraw(animation);\n }\n }\n\n // Fire the event with a default handler of removing the point\n if (withEvent !== false) {\n fireEvent(series, 'remove', null, remove);\n } else {\n remove();\n }\n },\n\n /**\n * Update the series with a new set of options. For a clean and precise\n * handling of new options, all methods and elements from the series are\n * removed, and it is initiated from scratch. Therefore, this method is more\n * performance expensive than some other utility methods like {@link\n * Series#setData} or {@link Series#setVisible}.\n *\n * @param {SeriesOptions} options\n * New options that will be merged with the series' existing\n * options.\n * @param {Boolean} [redraw=true]\n * Whether to redraw the chart after the series is altered. If doing\n * more operations on the chart, it is a good idea to set redraw to\n * false and call {@link Chart#redraw} after.\n *\n * @sample highcharts/members/series-update/\n * Updating series options\n * @sample maps/members/series-update/\n * Update series options in Highmaps\n */\n update: function(newOptions, redraw) {\n var series = this,\n chart = series.chart,\n // must use user options when changing type because series.options\n // is merged in with type specific plotOptions\n oldOptions = series.userOptions,\n oldType = series.oldType || series.type,\n newType = newOptions.type || oldOptions.type || chart.options.chart.type,\n proto = seriesTypes[oldType].prototype,\n preserve = ['group', 'markerGroup', 'dataLabelsGroup'],\n n;\n\n // Running Series.update to update the data only is an intuitive usage,\n // so we want to make sure that when used like this, we run the\n // cheaper setData function and allow animation instead of completely\n // recreating the series instance.\n if (Object.keys && Object.keys(newOptions).toString() === 'data') {\n return this.setData(newOptions.data, redraw);\n }\n\n // If we're changing type or zIndex, create new groups (#3380, #3404)\n if ((newType && newType !== oldType) || newOptions.zIndex !== undefined) {\n preserve.length = 0;\n }\n\n // Make sure groups are not destroyed (#3094)\n each(preserve, function(prop) {\n preserve[prop] = series[prop];\n delete series[prop];\n });\n\n // Do the merge, with some forced options\n newOptions = merge(oldOptions, {\n animation: false,\n index: series.index,\n pointStart: series.xData[0] // when updating after addPoint\n }, {\n data: series.options.data\n }, newOptions);\n\n // Destroy the series and delete all properties. Reinsert all methods\n // and properties from the new type prototype (#2270, #3719)\n series.remove(false, null, false);\n for (n in proto) {\n series[n] = undefined;\n }\n extend(series, seriesTypes[newType || oldType].prototype);\n\n // Re-register groups (#3094)\n each(preserve, function(prop) {\n series[prop] = preserve[prop];\n });\n\n series.init(chart, newOptions);\n series.oldType = oldType;\n chart.linkSeries(); // Links are lost in series.remove (#3028)\n if (pick(redraw, true)) {\n chart.redraw(false);\n }\n }\n });\n\n // Extend the Axis.prototype for dynamic methods\n extend(Axis.prototype, /** @lends Highcharts.Axis.prototype */ {\n\n /**\n * Update an axis object with a new set of options. The options are merged\n * with the existing options, so only new or altered options need to be\n * specified.\n *\n * @param {Object} options\n * The new options that will be merged in with existing options on\n * the axis.\n * @sample highcharts/members/axis-update/ Axis update demo\n */\n update: function(options, redraw) {\n var chart = this.chart;\n\n options = chart.options[this.coll][this.options.index] =\n merge(this.userOptions, options);\n\n this.destroy(true);\n\n this.init(chart, extend(options, {\n events: undefined\n }));\n\n chart.isDirtyBox = true;\n if (pick(redraw, true)) {\n chart.redraw();\n }\n },\n\n /**\n * Remove the axis from the chart.\n *\n * @param {Boolean} [redraw=true] Whether to redraw the chart following the\n * remove.\n *\n * @sample highcharts/members/chart-addaxis/ Add and remove axes\n */\n remove: function(redraw) {\n var chart = this.chart,\n key = this.coll, // xAxis or yAxis\n axisSeries = this.series,\n i = axisSeries.length;\n\n // Remove associated series (#2687)\n while (i--) {\n if (axisSeries[i]) {\n axisSeries[i].remove(false);\n }\n }\n\n // Remove the axis\n erase(chart.axes, this);\n erase(chart[key], this);\n\n if (isArray(chart.options[key])) {\n chart.options[key].splice(this.options.index, 1);\n } else { // color axis, #6488\n delete chart.options[key];\n }\n\n each(chart[key], function(axis, i) { // Re-index, #1706\n axis.options.index = i;\n });\n this.destroy();\n chart.isDirtyBox = true;\n\n if (pick(redraw, true)) {\n chart.redraw();\n }\n },\n\n /**\n * Update the axis title by options after render time.\n *\n * @param {TitleOptions} titleOptions\n * The additional title options.\n * @param {Boolean} [redraw=true]\n * Whether to redraw the chart after setting the title.\n * @sample highcharts/members/axis-settitle/ Set a new Y axis title\n */\n setTitle: function(titleOptions, redraw) {\n this.update({\n title: titleOptions\n }, redraw);\n },\n\n /**\n * Set new axis categories and optionally redraw.\n * @param {Array.} categories - The new categories.\n * @param {Boolean} [redraw=true] - Whether to redraw the chart.\n * @sample highcharts/members/axis-setcategories/ Set categories by click on\n * a button\n */\n setCategories: function(categories, redraw) {\n this.update({\n categories: categories\n }, redraw);\n }\n\n });\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var color = H.color,\n each = H.each,\n LegendSymbolMixin = H.LegendSymbolMixin,\n map = H.map,\n pick = H.pick,\n Series = H.Series,\n seriesType = H.seriesType;\n\n /**\n * Area series type.\n * @constructor seriesTypes.area\n * @extends {Series}\n */\n seriesType('area', 'line', {\n softThreshold: false,\n threshold: 0\n // trackByArea: false,\n // lineColor: null, // overrides color, but lets fillColor be unaltered\n // fillOpacity: 0.75,\n // fillColor: null\n }, /** @lends seriesTypes.area.prototype */ {\n singleStacks: false,\n /** \n * Return an array of stacked points, where null and missing points are replaced by \n * dummy points in order for gaps to be drawn correctly in stacks.\n */\n getStackPoints: function() {\n var series = this,\n segment = [],\n keys = [],\n xAxis = this.xAxis,\n yAxis = this.yAxis,\n stack = yAxis.stacks[this.stackKey],\n pointMap = {},\n points = this.points,\n seriesIndex = series.index,\n yAxisSeries = yAxis.series,\n seriesLength = yAxisSeries.length,\n visibleSeries,\n upOrDown = pick(yAxis.options.reversedStacks, true) ? 1 : -1,\n i;\n\n if (this.options.stacking) {\n // Create a map where we can quickly look up the points by their X value.\n for (i = 0; i < points.length; i++) {\n pointMap[points[i].x] = points[i];\n }\n\n // Sort the keys (#1651)\n H.objectEach(stack, function(stackX, x) {\n if (stackX.total !== null) { // nulled after switching between grouping and not (#1651, #2336)\n keys.push(x);\n }\n });\n keys.sort(function(a, b) {\n return a - b;\n });\n\n visibleSeries = map(yAxisSeries, function() {\n return this.visible;\n });\n\n each(keys, function(x, idx) {\n var y = 0,\n stackPoint,\n stackedValues;\n\n if (pointMap[x] && !pointMap[x].isNull) {\n segment.push(pointMap[x]);\n\n // Find left and right cliff. -1 goes left, 1 goes right.\n each([-1, 1], function(direction) {\n var nullName = direction === 1 ? 'rightNull' : 'leftNull',\n cliffName = direction === 1 ? 'rightCliff' : 'leftCliff',\n cliff = 0,\n otherStack = stack[keys[idx + direction]];\n\n // If there is a stack next to this one, to the left or to the right...\n if (otherStack) {\n i = seriesIndex;\n while (i >= 0 && i < seriesLength) { // Can go either up or down, depending on reversedStacks\n stackPoint = otherStack.points[i];\n if (!stackPoint) {\n // If the next point in this series is missing, mark the point\n // with point.leftNull or point.rightNull = true.\n if (i === seriesIndex) {\n pointMap[x][nullName] = true;\n\n // If there are missing points in the next stack in any of the \n // series below this one, we need to substract the missing values\n // and add a hiatus to the left or right.\n } else if (visibleSeries[i]) {\n stackedValues = stack[x].points[i];\n if (stackedValues) {\n cliff -= stackedValues[1] - stackedValues[0];\n }\n }\n }\n // When reversedStacks is true, loop up, else loop down\n i += upOrDown;\n }\n }\n pointMap[x][cliffName] = cliff;\n });\n\n\n // There is no point for this X value in this series, so we \n // insert a dummy point in order for the areas to be drawn\n // correctly.\n } else {\n\n // Loop down the stack to find the series below this one that has\n // a value (#1991)\n i = seriesIndex;\n while (i >= 0 && i < seriesLength) {\n stackPoint = stack[x].points[i];\n if (stackPoint) {\n y = stackPoint[1];\n break;\n }\n // When reversedStacks is true, loop up, else loop down\n i += upOrDown;\n }\n y = yAxis.translate(y, 0, 1, 0, 1); // #6272\n segment.push({\n isNull: true,\n plotX: xAxis.translate(x, 0, 0, 0, 1), // #6272\n x: x,\n plotY: y,\n yBottom: y\n });\n }\n });\n\n }\n\n return segment;\n },\n\n getGraphPath: function(points) {\n var getGraphPath = Series.prototype.getGraphPath,\n graphPath,\n options = this.options,\n stacking = options.stacking,\n yAxis = this.yAxis,\n topPath,\n //topPoints = [],\n bottomPath,\n bottomPoints = [],\n graphPoints = [],\n seriesIndex = this.index,\n i,\n areaPath,\n plotX,\n stacks = yAxis.stacks[this.stackKey],\n threshold = options.threshold,\n translatedThreshold = yAxis.getThreshold(options.threshold),\n isNull,\n yBottom,\n connectNulls = options.connectNulls || stacking === 'percent',\n /**\n * To display null points in underlying stacked series, this series graph must be \n * broken, and the area also fall down to fill the gap left by the null point. #2069\n */\n addDummyPoints = function(i, otherI, side) {\n var point = points[i],\n stackedValues = stacking && stacks[point.x].points[seriesIndex],\n nullVal = point[side + 'Null'] || 0,\n cliffVal = point[side + 'Cliff'] || 0,\n top,\n bottom,\n isNull = true;\n\n if (cliffVal || nullVal) {\n\n top = (nullVal ? stackedValues[0] : stackedValues[1]) + cliffVal;\n bottom = stackedValues[0] + cliffVal;\n isNull = !!nullVal;\n\n } else if (!stacking && points[otherI] && points[otherI].isNull) {\n top = bottom = threshold;\n }\n\n // Add to the top and bottom line of the area\n if (top !== undefined) {\n graphPoints.push({\n plotX: plotX,\n plotY: top === null ? translatedThreshold : yAxis.getThreshold(top),\n isNull: isNull,\n isCliff: true\n });\n bottomPoints.push({\n plotX: plotX,\n plotY: bottom === null ? translatedThreshold : yAxis.getThreshold(bottom),\n doCurve: false // #1041, gaps in areaspline areas\n });\n }\n };\n\n // Find what points to use\n points = points || this.points;\n\n // Fill in missing points\n if (stacking) {\n points = this.getStackPoints();\n }\n\n for (i = 0; i < points.length; i++) {\n isNull = points[i].isNull;\n plotX = pick(points[i].rectPlotX, points[i].plotX);\n yBottom = pick(points[i].yBottom, translatedThreshold);\n\n if (!isNull || connectNulls) {\n\n if (!connectNulls) {\n addDummyPoints(i, i - 1, 'left');\n }\n\n if (!(isNull && !stacking && connectNulls)) { // Skip null point when stacking is false and connectNulls true\n graphPoints.push(points[i]);\n bottomPoints.push({\n x: i,\n plotX: plotX,\n plotY: yBottom\n });\n }\n\n if (!connectNulls) {\n addDummyPoints(i, i + 1, 'right');\n }\n }\n }\n\n topPath = getGraphPath.call(this, graphPoints, true, true);\n\n bottomPoints.reversed = true;\n bottomPath = getGraphPath.call(this, bottomPoints, true, true);\n if (bottomPath.length) {\n bottomPath[0] = 'L';\n }\n\n areaPath = topPath.concat(bottomPath);\n graphPath = getGraphPath.call(this, graphPoints, false, connectNulls); // TODO: don't set leftCliff and rightCliff when connectNulls?\n\n areaPath.xMap = topPath.xMap;\n this.areaPath = areaPath;\n\n return graphPath;\n },\n\n /**\n * Draw the graph and the underlying area. This method calls the Series base\n * function and adds the area. The areaPath is calculated in the getSegmentPath\n * method called from Series.prototype.drawGraph.\n */\n drawGraph: function() {\n\n // Define or reset areaPath\n this.areaPath = [];\n\n // Call the base method\n Series.prototype.drawGraph.apply(this);\n\n // Define local variables\n var series = this,\n areaPath = this.areaPath,\n options = this.options,\n zones = this.zones,\n props = [\n [\n 'area',\n 'highcharts-area',\n\n this.color,\n options.fillColor\n\n ]\n ]; // area name, main color, fill color\n\n each(zones, function(zone, i) {\n props.push([\n 'zone-area-' + i,\n 'highcharts-area highcharts-zone-area-' + i + ' ' + zone.className,\n\n zone.color || series.color,\n zone.fillColor || options.fillColor\n\n ]);\n });\n\n each(props, function(prop) {\n var areaKey = prop[0],\n area = series[areaKey];\n\n // Create or update the area\n if (area) { // update\n area.endX = areaPath.xMap;\n area.animate({\n d: areaPath\n });\n\n } else { // create\n area = series[areaKey] = series.chart.renderer.path(areaPath)\n .addClass(prop[1])\n .attr({\n\n fill: pick(\n prop[3],\n color(prop[2]).setOpacity(pick(options.fillOpacity, 0.75)).get()\n ),\n\n zIndex: 0 // #1069\n }).add(series.group);\n area.isArea = true;\n }\n area.startX = areaPath.xMap;\n area.shiftUnit = options.step ? 2 : 1;\n });\n },\n\n drawLegendSymbol: LegendSymbolMixin.drawRectangle\n });\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var pick = H.pick,\n seriesType = H.seriesType;\n\n /**\n * Spline series type.\n * @constructor seriesTypes.spline\n * @extends {Series}\n */\n seriesType('spline', 'line', {}, /** @lends seriesTypes.spline.prototype */ {\n /**\n * Get the spline segment from a given point's previous neighbour to the given point\n */\n getPointSpline: function(points, point, i) {\n var smoothing = 1.5, // 1 means control points midway between points, 2 means 1/3 from the point, 3 is 1/4 etc\n denom = smoothing + 1,\n plotX = point.plotX,\n plotY = point.plotY,\n lastPoint = points[i - 1],\n nextPoint = points[i + 1],\n leftContX,\n leftContY,\n rightContX,\n rightContY,\n ret;\n\n function doCurve(otherPoint) {\n return otherPoint &&\n !otherPoint.isNull &&\n otherPoint.doCurve !== false &&\n !point.isCliff; // #6387, area splines next to null\n }\n\n // Find control points\n if (doCurve(lastPoint) && doCurve(nextPoint)) {\n var lastX = lastPoint.plotX,\n lastY = lastPoint.plotY,\n nextX = nextPoint.plotX,\n nextY = nextPoint.plotY,\n correction = 0;\n\n leftContX = (smoothing * plotX + lastX) / denom;\n leftContY = (smoothing * plotY + lastY) / denom;\n rightContX = (smoothing * plotX + nextX) / denom;\n rightContY = (smoothing * plotY + nextY) / denom;\n\n // Have the two control points make a straight line through main point\n if (rightContX !== leftContX) { // #5016, division by zero\n correction = ((rightContY - leftContY) * (rightContX - plotX)) /\n (rightContX - leftContX) + plotY - rightContY;\n }\n\n leftContY += correction;\n rightContY += correction;\n\n // to prevent false extremes, check that control points are between\n // neighbouring points' y values\n if (leftContY > lastY && leftContY > plotY) {\n leftContY = Math.max(lastY, plotY);\n rightContY = 2 * plotY - leftContY; // mirror of left control point\n } else if (leftContY < lastY && leftContY < plotY) {\n leftContY = Math.min(lastY, plotY);\n rightContY = 2 * plotY - leftContY;\n }\n if (rightContY > nextY && rightContY > plotY) {\n rightContY = Math.max(nextY, plotY);\n leftContY = 2 * plotY - rightContY;\n } else if (rightContY < nextY && rightContY < plotY) {\n rightContY = Math.min(nextY, plotY);\n leftContY = 2 * plotY - rightContY;\n }\n\n // record for drawing in next point\n point.rightContX = rightContX;\n point.rightContY = rightContY;\n\n\n }\n\n // Visualize control points for debugging\n /*\n if (leftContX) {\n this.chart.renderer.circle(leftContX + this.chart.plotLeft, leftContY + this.chart.plotTop, 2)\n .attr({\n stroke: 'red',\n 'stroke-width': 2,\n fill: 'none',\n zIndex: 9\n })\n .add();\n this.chart.renderer.path(['M', leftContX + this.chart.plotLeft, leftContY + this.chart.plotTop,\n 'L', plotX + this.chart.plotLeft, plotY + this.chart.plotTop])\n .attr({\n stroke: 'red',\n 'stroke-width': 2,\n zIndex: 9\n })\n .add();\n }\n if (rightContX) {\n this.chart.renderer.circle(rightContX + this.chart.plotLeft, rightContY + this.chart.plotTop, 2)\n .attr({\n stroke: 'green',\n 'stroke-width': 2,\n fill: 'none',\n zIndex: 9\n })\n .add();\n this.chart.renderer.path(['M', rightContX + this.chart.plotLeft, rightContY + this.chart.plotTop,\n 'L', plotX + this.chart.plotLeft, plotY + this.chart.plotTop])\n .attr({\n stroke: 'green',\n 'stroke-width': 2,\n zIndex: 9\n })\n .add();\n }\n // */\n ret = [\n 'C',\n pick(lastPoint.rightContX, lastPoint.plotX),\n pick(lastPoint.rightContY, lastPoint.plotY),\n pick(leftContX, plotX),\n pick(leftContY, plotY),\n plotX,\n plotY\n ];\n lastPoint.rightContX = lastPoint.rightContY = null; // reset for updating series later\n return ret;\n }\n });\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var areaProto = H.seriesTypes.area.prototype,\n defaultPlotOptions = H.defaultPlotOptions,\n LegendSymbolMixin = H.LegendSymbolMixin,\n seriesType = H.seriesType;\n /**\n * AreaSplineSeries object\n */\n seriesType('areaspline', 'spline', defaultPlotOptions.area, {\n getStackPoints: areaProto.getStackPoints,\n getGraphPath: areaProto.getGraphPath,\n setStackCliffs: areaProto.setStackCliffs,\n drawGraph: areaProto.drawGraph,\n drawLegendSymbol: LegendSymbolMixin.drawRectangle\n });\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var animObject = H.animObject,\n color = H.color,\n each = H.each,\n extend = H.extend,\n isNumber = H.isNumber,\n LegendSymbolMixin = H.LegendSymbolMixin,\n merge = H.merge,\n noop = H.noop,\n pick = H.pick,\n Series = H.Series,\n seriesType = H.seriesType,\n svg = H.svg;\n /**\n * The column series type.\n *\n * @constructor seriesTypes.column\n * @augments Series\n */\n seriesType('column', 'line', {\n borderRadius: 0,\n //colorByPoint: undefined,\n crisp: true,\n groupPadding: 0.2,\n //grouping: true,\n marker: null, // point options are specified in the base options\n pointPadding: 0.1,\n //pointWidth: null,\n minPointLength: 0,\n cropThreshold: 50, // when there are more points, they will not animate out of the chart on xAxis.setExtremes\n pointRange: null, // null means auto, meaning 1 in a categorized axis and least distance between points if not categories\n states: {\n hover: {\n halo: false,\n\n brightness: 0.1,\n shadow: false\n\n },\n\n select: {\n color: '#cccccc',\n borderColor: '#000000',\n shadow: false\n }\n\n },\n dataLabels: {\n align: null, // auto\n verticalAlign: null, // auto\n y: null\n },\n softThreshold: false,\n startFromThreshold: true, // false doesn't work well: http://jsfiddle.net/highcharts/hz8fopan/14/\n stickyTracking: false,\n tooltip: {\n distance: 6\n },\n threshold: 0,\n\n borderColor: '#ffffff'\n // borderWidth: 1\n\n\n }, /** @lends seriesTypes.column.prototype */ {\n cropShoulder: 0,\n directTouch: true, // When tooltip is not shared, this series (and derivatives) requires direct touch/hover. KD-tree does not apply.\n trackerGroups: ['group', 'dataLabelsGroup'],\n negStacks: true, // use separate negative stacks, unlike area stacks where a negative\n // point is substracted from previous (#1910)\n\n /**\n * Initialize the series. Extends the basic Series.init method by\n * marking other series of the same type as dirty.\n *\n * @function #init\n * @memberOf seriesTypes.column\n * @returns {void}\n */\n init: function() {\n Series.prototype.init.apply(this, arguments);\n\n var series = this,\n chart = series.chart;\n\n // if the series is added dynamically, force redraw of other\n // series affected by a new column\n if (chart.hasRendered) {\n each(chart.series, function(otherSeries) {\n if (otherSeries.type === series.type) {\n otherSeries.isDirty = true;\n }\n });\n }\n },\n\n /**\n * Return the width and x offset of the columns adjusted for grouping, groupPadding, pointPadding,\n * pointWidth etc.\n */\n getColumnMetrics: function() {\n\n var series = this,\n options = series.options,\n xAxis = series.xAxis,\n yAxis = series.yAxis,\n reversedXAxis = xAxis.reversed,\n stackKey,\n stackGroups = {},\n columnCount = 0;\n\n // Get the total number of column type series.\n // This is called on every series. Consider moving this logic to a\n // chart.orderStacks() function and call it on init, addSeries and removeSeries\n if (options.grouping === false) {\n columnCount = 1;\n } else {\n each(series.chart.series, function(otherSeries) {\n var otherOptions = otherSeries.options,\n otherYAxis = otherSeries.yAxis,\n columnIndex;\n if (\n otherSeries.type === series.type &&\n (\n otherSeries.visible ||\n !series.chart.options.chart.ignoreHiddenSeries\n ) &&\n yAxis.len === otherYAxis.len &&\n yAxis.pos === otherYAxis.pos\n ) { // #642, #2086\n if (otherOptions.stacking) {\n stackKey = otherSeries.stackKey;\n if (stackGroups[stackKey] === undefined) {\n stackGroups[stackKey] = columnCount++;\n }\n columnIndex = stackGroups[stackKey];\n } else if (otherOptions.grouping !== false) { // #1162\n columnIndex = columnCount++;\n }\n otherSeries.columnIndex = columnIndex;\n }\n });\n }\n\n var categoryWidth = Math.min(\n Math.abs(xAxis.transA) * (xAxis.ordinalSlope || options.pointRange || xAxis.closestPointRange || xAxis.tickInterval || 1), // #2610\n xAxis.len // #1535\n ),\n groupPadding = categoryWidth * options.groupPadding,\n groupWidth = categoryWidth - 2 * groupPadding,\n pointOffsetWidth = groupWidth / (columnCount || 1),\n pointWidth = Math.min(\n options.maxPointWidth || xAxis.len,\n pick(options.pointWidth, pointOffsetWidth * (1 - 2 * options.pointPadding))\n ),\n pointPadding = (pointOffsetWidth - pointWidth) / 2,\n colIndex = (series.columnIndex || 0) + (reversedXAxis ? 1 : 0), // #1251, #3737\n pointXOffset = pointPadding + (groupPadding + colIndex *\n pointOffsetWidth - (categoryWidth / 2)) *\n (reversedXAxis ? -1 : 1);\n\n // Save it for reading in linked series (Error bars particularly)\n series.columnMetrics = {\n width: pointWidth,\n offset: pointXOffset\n };\n return series.columnMetrics;\n\n },\n\n /**\n * Make the columns crisp. The edges are rounded to the nearest full pixel.\n */\n crispCol: function(x, y, w, h) {\n var chart = this.chart,\n borderWidth = this.borderWidth,\n xCrisp = -(borderWidth % 2 ? 0.5 : 0),\n yCrisp = borderWidth % 2 ? 0.5 : 1,\n right,\n bottom,\n fromTop;\n\n if (chart.inverted && chart.renderer.isVML) {\n yCrisp += 1;\n }\n\n // Horizontal. We need to first compute the exact right edge, then round it\n // and compute the width from there.\n if (this.options.crisp) {\n right = Math.round(x + w) + xCrisp;\n x = Math.round(x) + xCrisp;\n w = right - x;\n }\n\n // Vertical\n bottom = Math.round(y + h) + yCrisp;\n fromTop = Math.abs(y) <= 0.5 && bottom > 0.5; // #4504, #4656\n y = Math.round(y) + yCrisp;\n h = bottom - y;\n\n // Top edges are exceptions\n if (fromTop && h) { // #5146\n y -= 1;\n h += 1;\n }\n\n return {\n x: x,\n y: y,\n width: w,\n height: h\n };\n },\n\n /**\n * Translate each point to the plot area coordinate system and find shape positions\n */\n translate: function() {\n var series = this,\n chart = series.chart,\n options = series.options,\n dense = series.dense = series.closestPointRange * series.xAxis.transA < 2,\n borderWidth = series.borderWidth = pick(\n options.borderWidth,\n dense ? 0 : 1 // #3635\n ),\n yAxis = series.yAxis,\n threshold = options.threshold,\n translatedThreshold = series.translatedThreshold = yAxis.getThreshold(threshold),\n minPointLength = pick(options.minPointLength, 5),\n metrics = series.getColumnMetrics(),\n pointWidth = metrics.width,\n seriesBarW = series.barW = Math.max(pointWidth, 1 + 2 * borderWidth), // postprocessed for border width\n pointXOffset = series.pointXOffset = metrics.offset;\n\n if (chart.inverted) {\n translatedThreshold -= 0.5; // #3355\n }\n\n // When the pointPadding is 0, we want the columns to be packed tightly, so we allow individual\n // columns to have individual sizes. When pointPadding is greater, we strive for equal-width\n // columns (#2694).\n if (options.pointPadding) {\n seriesBarW = Math.ceil(seriesBarW);\n }\n\n Series.prototype.translate.apply(series);\n\n // Record the new values\n each(series.points, function(point) {\n var yBottom = pick(point.yBottom, translatedThreshold),\n safeDistance = 999 + Math.abs(yBottom),\n plotY = Math.min(Math.max(-safeDistance, point.plotY), yAxis.len + safeDistance), // Don't draw too far outside plot area (#1303, #2241, #4264)\n barX = point.plotX + pointXOffset,\n barW = seriesBarW,\n barY = Math.min(plotY, yBottom),\n up,\n barH = Math.max(plotY, yBottom) - barY;\n\n // Handle options.minPointLength\n if (Math.abs(barH) < minPointLength) {\n if (minPointLength) {\n barH = minPointLength;\n up = (!yAxis.reversed && !point.negative) || (yAxis.reversed && point.negative);\n barY = Math.abs(barY - translatedThreshold) > minPointLength ? // stacked\n yBottom - minPointLength : // keep position\n translatedThreshold - (up ? minPointLength : 0); // #1485, #4051\n }\n }\n\n // Cache for access in polar\n point.barX = barX;\n point.pointWidth = pointWidth;\n\n // Fix the tooltip on center of grouped columns (#1216, #424, #3648)\n point.tooltipPos = chart.inverted ? [yAxis.len + yAxis.pos - chart.plotLeft - plotY, series.xAxis.len - barX - barW / 2, barH] : [barX + barW / 2, plotY + yAxis.pos - chart.plotTop, barH];\n\n // Register shape type and arguments to be used in drawPoints\n point.shapeType = 'rect';\n point.shapeArgs = series.crispCol.apply(\n series,\n point.isNull ?\n // #3169, drilldown from null must have a position to work from\n // #6585, dataLabel should be placed on xAxis, not floating in the middle of the chart\n [barX, translatedThreshold, barW, 0] : [barX, barY, barW, barH]\n );\n });\n\n },\n\n getSymbol: noop,\n\n /**\n * Use a solid rectangle like the area series types\n */\n drawLegendSymbol: LegendSymbolMixin.drawRectangle,\n\n\n /**\n * Columns have no graph\n */\n drawGraph: function() {\n this.group[this.dense ? 'addClass' : 'removeClass']('highcharts-dense-data');\n },\n\n\n /**\n * Get presentational attributes\n */\n pointAttribs: function(point, state) {\n var options = this.options,\n stateOptions,\n ret,\n p2o = this.pointAttrToOptions || {},\n strokeOption = p2o.stroke || 'borderColor',\n strokeWidthOption = p2o['stroke-width'] || 'borderWidth',\n fill = (point && point.color) || this.color,\n stroke = point[strokeOption] || options[strokeOption] ||\n this.color || fill, // set to fill when borderColor null\n strokeWidth = point[strokeWidthOption] ||\n options[strokeWidthOption] || this[strokeWidthOption] || 0,\n dashstyle = options.dashStyle,\n zone,\n brightness;\n\n // Handle zone colors\n if (point && this.zones.length) {\n zone = point.getZone();\n fill = point.options.color || (zone && zone.color) || this.color; // When zones are present, don't use point.color (#4267). Changed order (#6527)\n }\n\n // Select or hover states\n if (state) {\n stateOptions = merge(\n options.states[state],\n point.options.states && point.options.states[state] || {} // #6401\n );\n brightness = stateOptions.brightness;\n fill = stateOptions.color ||\n (brightness !== undefined && color(fill).brighten(stateOptions.brightness).get()) ||\n fill;\n stroke = stateOptions[strokeOption] || stroke;\n strokeWidth = stateOptions[strokeWidthOption] || strokeWidth;\n dashstyle = stateOptions.dashStyle || dashstyle;\n }\n\n ret = {\n 'fill': fill,\n 'stroke': stroke,\n 'stroke-width': strokeWidth\n };\n if (options.borderRadius) {\n ret.r = options.borderRadius;\n }\n\n if (dashstyle) {\n ret.dashstyle = dashstyle;\n }\n\n return ret;\n },\n\n\n /**\n * Draw the columns. For bars, the series.group is rotated, so the same coordinates\n * apply for columns and bars. This method is inherited by scatter series.\n *\n */\n drawPoints: function() {\n var series = this,\n chart = this.chart,\n options = series.options,\n renderer = chart.renderer,\n animationLimit = options.animationLimit || 250,\n shapeArgs;\n\n // draw the columns\n each(series.points, function(point) {\n var plotY = point.plotY,\n graphic = point.graphic;\n\n if (isNumber(plotY) && point.y !== null) {\n shapeArgs = point.shapeArgs;\n\n if (graphic) { // update\n graphic[chart.pointCount < animationLimit ? 'animate' : 'attr'](\n merge(shapeArgs)\n );\n\n } else {\n point.graphic = graphic = renderer[point.shapeType](shapeArgs)\n .add(point.group || series.group);\n }\n\n\n // Presentational\n graphic\n .attr(series.pointAttribs(point, point.selected && 'select'))\n .shadow(options.shadow, null, options.stacking && !options.borderRadius);\n\n\n graphic.addClass(point.getClassName(), true);\n\n\n } else if (graphic) {\n point.graphic = graphic.destroy(); // #1269\n }\n });\n },\n\n /**\n * Animate the column heights one by one from zero\n * @param {Boolean} init Whether to initialize the animation or run it\n */\n animate: function(init) {\n var series = this,\n yAxis = this.yAxis,\n options = series.options,\n inverted = this.chart.inverted,\n attr = {},\n translatedThreshold;\n\n if (svg) { // VML is too slow anyway\n if (init) {\n attr.scaleY = 0.001;\n translatedThreshold = Math.min(yAxis.pos + yAxis.len, Math.max(yAxis.pos, yAxis.toPixels(options.threshold)));\n if (inverted) {\n attr.translateX = translatedThreshold - yAxis.len;\n } else {\n attr.translateY = translatedThreshold;\n }\n series.group.attr(attr);\n\n } else { // run the animation\n\n attr[inverted ? 'translateX' : 'translateY'] = yAxis.pos;\n series.group.animate(attr, extend(animObject(series.options.animation), {\n // Do the scale synchronously to ensure smooth updating (#5030)\n step: function(val, fx) {\n series.group.attr({\n scaleY: Math.max(0.001, fx.pos) // #5250\n });\n }\n }));\n\n // delete this function to allow it only once\n series.animate = null;\n }\n }\n },\n\n /**\n * Remove this series from the chart\n */\n remove: function() {\n var series = this,\n chart = series.chart;\n\n // column and bar series affects other series of the same type\n // as they are either stacked or grouped\n if (chart.hasRendered) {\n each(chart.series, function(otherSeries) {\n if (otherSeries.type === series.type) {\n otherSeries.isDirty = true;\n }\n });\n }\n\n Series.prototype.remove.apply(series, arguments);\n }\n });\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n\n var seriesType = H.seriesType;\n\n /**\n * The Bar series class\n */\n seriesType('bar', 'column', null, {\n inverted: true\n });\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var Series = H.Series,\n seriesType = H.seriesType;\n /**\n * The scatter series type\n */\n seriesType('scatter', 'line', {\n lineWidth: 0,\n findNearestPointBy: 'xy',\n marker: {\n enabled: true // Overrides auto-enabling in line series (#3647)\n },\n tooltip: {\n\n headerFormat: '\\u25CF ' +\n ' {series.name}
',\n\n pointFormat: 'x: {point.x}
y: {point.y}
'\n }\n\n // Prototype members\n }, {\n sorted: false,\n requireSorting: false,\n noSharedTooltip: true,\n trackerGroups: ['group', 'markerGroup', 'dataLabelsGroup'],\n takeOrdinalPosition: false, // #2342\n drawGraph: function() {\n if (this.options.lineWidth) {\n Series.prototype.drawGraph.call(this);\n }\n }\n });\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var pick = H.pick,\n relativeLength = H.relativeLength;\n\n H.CenteredSeriesMixin = {\n /**\n * Get the center of the pie based on the size and center options relative to the\n * plot area. Borrowed by the polar and gauge series types.\n */\n getCenter: function() {\n\n var options = this.options,\n chart = this.chart,\n slicingRoom = 2 * (options.slicedOffset || 0),\n handleSlicingRoom,\n plotWidth = chart.plotWidth - 2 * slicingRoom,\n plotHeight = chart.plotHeight - 2 * slicingRoom,\n centerOption = options.center,\n positions = [pick(centerOption[0], '50%'), pick(centerOption[1], '50%'), options.size || '100%', options.innerSize || 0],\n smallestSize = Math.min(plotWidth, plotHeight),\n i,\n value;\n\n for (i = 0; i < 4; ++i) {\n value = positions[i];\n handleSlicingRoom = i < 2 || (i === 2 && /%$/.test(value));\n\n // i == 0: centerX, relative to width\n // i == 1: centerY, relative to height\n // i == 2: size, relative to smallestSize\n // i == 3: innerSize, relative to size\n positions[i] = relativeLength(value, [plotWidth, plotHeight, smallestSize, positions[2]][i]) +\n (handleSlicingRoom ? slicingRoom : 0);\n\n }\n // innerSize cannot be larger than size (#3632)\n if (positions[3] > positions[2]) {\n positions[3] = positions[2];\n }\n return positions;\n }\n };\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var addEvent = H.addEvent,\n CenteredSeriesMixin = H.CenteredSeriesMixin,\n defined = H.defined,\n each = H.each,\n extend = H.extend,\n inArray = H.inArray,\n LegendSymbolMixin = H.LegendSymbolMixin,\n noop = H.noop,\n pick = H.pick,\n Point = H.Point,\n Series = H.Series,\n seriesType = H.seriesType,\n seriesTypes = H.seriesTypes,\n setAnimation = H.setAnimation;\n\n /**\n * The pie series type.\n *\n * @constructor seriesTypes.pie\n * @augments Series\n */\n seriesType('pie', 'line', {\n center: [null, null],\n clip: false,\n colorByPoint: true, // always true for pies\n dataLabels: {\n // align: null,\n // connectorWidth: 1,\n // connectorColor: point.color,\n // connectorPadding: 5,\n distance: 30,\n enabled: true,\n formatter: function() { // #2945\n return this.point.isNull ? undefined : this.point.name;\n },\n // softConnector: true,\n x: 0\n // y: 0\n },\n ignoreHiddenPoint: true,\n //innerSize: 0,\n legendType: 'point',\n marker: null, // point options are specified in the base options\n size: null,\n showInLegend: false,\n slicedOffset: 10,\n stickyTracking: false,\n tooltip: {\n followPointer: true\n },\n\n borderColor: '#ffffff',\n borderWidth: 1,\n states: {\n hover: {\n brightness: 0.1,\n shadow: false\n }\n }\n\n\n }, /** @lends seriesTypes.pie.prototype */ {\n isCartesian: false,\n requireSorting: false,\n directTouch: true,\n noSharedTooltip: true,\n trackerGroups: ['group', 'dataLabelsGroup'],\n axisTypes: [],\n pointAttribs: seriesTypes.column.prototype.pointAttribs,\n /**\n * Animate the pies in\n */\n animate: function(init) {\n var series = this,\n points = series.points,\n startAngleRad = series.startAngleRad;\n\n if (!init) {\n each(points, function(point) {\n var graphic = point.graphic,\n args = point.shapeArgs;\n\n if (graphic) {\n // start values\n graphic.attr({\n r: point.startR || (series.center[3] / 2), // animate from inner radius (#779)\n start: startAngleRad,\n end: startAngleRad\n });\n\n // animate\n graphic.animate({\n r: args.r,\n start: args.start,\n end: args.end\n }, series.options.animation);\n }\n });\n\n // delete this function to allow it only once\n series.animate = null;\n }\n },\n\n /**\n * Recompute total chart sum and update percentages of points.\n */\n updateTotals: function() {\n var i,\n total = 0,\n points = this.points,\n len = points.length,\n point,\n ignoreHiddenPoint = this.options.ignoreHiddenPoint;\n\n // Get the total sum\n for (i = 0; i < len; i++) {\n point = points[i];\n total += (ignoreHiddenPoint && !point.visible) ?\n 0 :\n point.isNull ? 0 : point.y;\n }\n this.total = total;\n\n // Set each point's properties\n for (i = 0; i < len; i++) {\n point = points[i];\n point.percentage = (total > 0 && (point.visible || !ignoreHiddenPoint)) ? point.y / total * 100 : 0;\n point.total = total;\n }\n },\n\n /**\n * Extend the generatePoints method by adding total and percentage properties to each point\n */\n generatePoints: function() {\n Series.prototype.generatePoints.call(this);\n this.updateTotals();\n },\n\n /**\n * Do translation for pie slices\n */\n translate: function(positions) {\n this.generatePoints();\n\n var series = this,\n cumulative = 0,\n precision = 1000, // issue #172\n options = series.options,\n slicedOffset = options.slicedOffset,\n connectorOffset = slicedOffset + (options.borderWidth || 0),\n finalConnectorOffset,\n start,\n end,\n angle,\n startAngle = options.startAngle || 0,\n startAngleRad = series.startAngleRad = Math.PI / 180 * (startAngle - 90),\n endAngleRad = series.endAngleRad = Math.PI / 180 * ((pick(options.endAngle, startAngle + 360)) - 90),\n circ = endAngleRad - startAngleRad, //2 * Math.PI,\n points = series.points,\n radiusX, // the x component of the radius vector for a given point\n radiusY,\n labelDistance = options.dataLabels.distance,\n ignoreHiddenPoint = options.ignoreHiddenPoint,\n i,\n len = points.length,\n point;\n\n // Get positions - either an integer or a percentage string must be given.\n // If positions are passed as a parameter, we're in a recursive loop for adjusting\n // space for data labels.\n if (!positions) {\n series.center = positions = series.getCenter();\n }\n\n // Utility for getting the x value from a given y, used for anticollision\n // logic in data labels.\n // Added point for using specific points' label distance.\n series.getX = function(y, left, point) {\n angle = Math.asin(Math.min((y - positions[1]) / (positions[2] / 2 + point.labelDistance), 1));\n return positions[0] +\n (left ? -1 : 1) *\n (Math.cos(angle) * (positions[2] / 2 + point.labelDistance));\n };\n\n // Calculate the geometry for each point\n for (i = 0; i < len; i++) {\n\n point = points[i];\n\n // Used for distance calculation for specific point.\n point.labelDistance = pick(\n point.options.dataLabels && point.options.dataLabels.distance,\n labelDistance\n );\n\n // Saved for later dataLabels distance calculation.\n series.maxLabelDistance = Math.max(series.maxLabelDistance || 0, point.labelDistance);\n\n // set start and end angle\n start = startAngleRad + (cumulative * circ);\n if (!ignoreHiddenPoint || point.visible) {\n cumulative += point.percentage / 100;\n }\n end = startAngleRad + (cumulative * circ);\n\n // set the shape\n point.shapeType = 'arc';\n point.shapeArgs = {\n x: positions[0],\n y: positions[1],\n r: positions[2] / 2,\n innerR: positions[3] / 2,\n start: Math.round(start * precision) / precision,\n end: Math.round(end * precision) / precision\n };\n\n // The angle must stay within -90 and 270 (#2645)\n angle = (end + start) / 2;\n if (angle > 1.5 * Math.PI) {\n angle -= 2 * Math.PI;\n } else if (angle < -Math.PI / 2) {\n angle += 2 * Math.PI;\n }\n\n // Center for the sliced out slice\n point.slicedTranslation = {\n translateX: Math.round(Math.cos(angle) * slicedOffset),\n translateY: Math.round(Math.sin(angle) * slicedOffset)\n };\n\n // set the anchor point for tooltips\n radiusX = Math.cos(angle) * positions[2] / 2;\n radiusY = Math.sin(angle) * positions[2] / 2;\n point.tooltipPos = [\n positions[0] + radiusX * 0.7,\n positions[1] + radiusY * 0.7\n ];\n\n point.half = angle < -Math.PI / 2 || angle > Math.PI / 2 ? 1 : 0;\n point.angle = angle;\n\n // Set the anchor point for data labels. Use point.labelDistance \n // instead of labelDistance // #1174\n // finalConnectorOffset - not override connectorOffset value.\n finalConnectorOffset = Math.min(connectorOffset, point.labelDistance / 5); // #1678\n point.labelPos = [\n positions[0] + radiusX + Math.cos(angle) * point.labelDistance, // first break of connector\n positions[1] + radiusY + Math.sin(angle) * point.labelDistance, // a/a\n positions[0] + radiusX + Math.cos(angle) * finalConnectorOffset, // second break, right outside pie\n positions[1] + radiusY + Math.sin(angle) * finalConnectorOffset, // a/a\n positions[0] + radiusX, // landing point for connector\n positions[1] + radiusY, // a/a\n point.labelDistance < 0 ? // alignment\n 'center' :\n point.half ? 'right' : 'left', // alignment\n angle // center angle\n ];\n\n }\n },\n\n drawGraph: null,\n\n /**\n * Draw the data points\n */\n drawPoints: function() {\n var series = this,\n chart = series.chart,\n renderer = chart.renderer,\n groupTranslation,\n //center,\n graphic,\n //group,\n pointAttr,\n shapeArgs;\n\n\n var shadow = series.options.shadow;\n if (shadow && !series.shadowGroup) {\n series.shadowGroup = renderer.g('shadow')\n .add(series.group);\n }\n\n\n // draw the slices\n each(series.points, function(point) {\n if (!point.isNull) {\n graphic = point.graphic;\n shapeArgs = point.shapeArgs;\n\n\n // If the point is sliced, use special translation, else use\n // plot area traslation\n groupTranslation = point.getTranslate();\n\n\n // Put the shadow behind all points\n var shadowGroup = point.shadowGroup;\n if (shadow && !shadowGroup) {\n shadowGroup = point.shadowGroup = renderer.g('shadow')\n .add(series.shadowGroup);\n }\n\n if (shadowGroup) {\n shadowGroup.attr(groupTranslation);\n }\n pointAttr = series.pointAttribs(point, point.selected && 'select');\n\n\n // Draw the slice\n if (graphic) {\n graphic\n .setRadialReference(series.center)\n\n .attr(pointAttr)\n\n .animate(extend(shapeArgs, groupTranslation));\n } else {\n\n point.graphic = graphic = renderer[point.shapeType](shapeArgs)\n .setRadialReference(series.center)\n .attr(groupTranslation)\n .add(series.group);\n\n if (!point.visible) {\n graphic.attr({\n visibility: 'hidden'\n });\n }\n\n\n graphic\n .attr(pointAttr)\n .attr({\n 'stroke-linejoin': 'round'\n })\n .shadow(shadow, shadowGroup);\n\n }\n\n graphic.addClass(point.getClassName());\n\n }\n });\n\n },\n\n\n searchPoint: noop,\n\n /**\n * Utility for sorting data labels\n */\n sortByAngle: function(points, sign) {\n points.sort(function(a, b) {\n return a.angle !== undefined && (b.angle - a.angle) * sign;\n });\n },\n\n /**\n * Use a simple symbol from LegendSymbolMixin\n */\n drawLegendSymbol: LegendSymbolMixin.drawRectangle,\n\n /**\n * Use the getCenter method from drawLegendSymbol\n */\n getCenter: CenteredSeriesMixin.getCenter,\n\n /**\n * Pies don't have point marker symbols\n */\n getSymbol: noop\n\n\n /**\n * @constructor seriesTypes.pie.prototype.pointClass\n * @extends {Point}\n */\n }, /** @lends seriesTypes.pie.prototype.pointClass.prototype */ {\n /**\n * Initiate the pie slice\n */\n init: function() {\n\n Point.prototype.init.apply(this, arguments);\n\n var point = this,\n toggleSlice;\n\n point.name = pick(point.name, 'Slice');\n\n // add event listener for select\n toggleSlice = function(e) {\n point.slice(e.type === 'select');\n };\n addEvent(point, 'select', toggleSlice);\n addEvent(point, 'unselect', toggleSlice);\n\n return point;\n },\n\n /**\n * Negative points are not valid (#1530, #3623, #5322)\n */\n isValid: function() {\n return H.isNumber(this.y, true) && this.y >= 0;\n },\n\n /**\n * Toggle the visibility of the pie slice\n * @param {Boolean} vis Whether to show the slice or not. If undefined, the\n * visibility is toggled\n */\n setVisible: function(vis, redraw) {\n var point = this,\n series = point.series,\n chart = series.chart,\n ignoreHiddenPoint = series.options.ignoreHiddenPoint;\n\n redraw = pick(redraw, ignoreHiddenPoint);\n\n if (vis !== point.visible) {\n\n // If called without an argument, toggle visibility\n point.visible = point.options.visible = vis = vis === undefined ? !point.visible : vis;\n series.options.data[inArray(point, series.data)] = point.options; // update userOptions.data\n\n // Show and hide associated elements. This is performed regardless of redraw or not,\n // because chart.redraw only handles full series.\n each(['graphic', 'dataLabel', 'connector', 'shadowGroup'], function(key) {\n if (point[key]) {\n point[key][vis ? 'show' : 'hide'](true);\n }\n });\n\n if (point.legendItem) {\n chart.legend.colorizeItem(point, vis);\n }\n\n // #4170, hide halo after hiding point\n if (!vis && point.state === 'hover') {\n point.setState('');\n }\n\n // Handle ignore hidden slices\n if (ignoreHiddenPoint) {\n series.isDirty = true;\n }\n\n if (redraw) {\n chart.redraw();\n }\n }\n },\n\n /**\n * Set or toggle whether the slice is cut out from the pie\n * @param {Boolean} sliced When undefined, the slice state is toggled\n * @param {Boolean} redraw Whether to redraw the chart. True by default.\n */\n slice: function(sliced, redraw, animation) {\n var point = this,\n series = point.series,\n chart = series.chart;\n\n setAnimation(animation, chart);\n\n // redraw is true by default\n redraw = pick(redraw, true);\n\n // if called without an argument, toggle\n point.sliced = point.options.sliced = sliced = defined(sliced) ? sliced : !point.sliced;\n series.options.data[inArray(point, series.data)] = point.options; // update userOptions.data\n\n point.graphic.animate(this.getTranslate());\n\n\n if (point.shadowGroup) {\n point.shadowGroup.animate(this.getTranslate());\n }\n\n },\n\n getTranslate: function() {\n return this.sliced ? this.slicedTranslation : {\n translateX: 0,\n translateY: 0\n };\n },\n\n haloPath: function(size) {\n var shapeArgs = this.shapeArgs;\n\n return this.sliced || !this.visible ? [] :\n this.series.chart.renderer.symbols.arc(\n shapeArgs.x,\n shapeArgs.y,\n shapeArgs.r + size,\n shapeArgs.r + size, {\n innerR: this.shapeArgs.r,\n start: shapeArgs.start,\n end: shapeArgs.end\n }\n );\n }\n });\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var addEvent = H.addEvent,\n arrayMax = H.arrayMax,\n defined = H.defined,\n each = H.each,\n extend = H.extend,\n format = H.format,\n map = H.map,\n merge = H.merge,\n noop = H.noop,\n pick = H.pick,\n relativeLength = H.relativeLength,\n Series = H.Series,\n seriesTypes = H.seriesTypes,\n stableSort = H.stableSort;\n\n\n /**\n * Generatl distribution algorithm for distributing labels of differing size along a\n * confined length in two dimensions. The algorithm takes an array of objects containing\n * a size, a target and a rank. It will place the labels as close as possible to their \n * targets, skipping the lowest ranked labels if necessary.\n */\n H.distribute = function(boxes, len) {\n\n var i,\n overlapping = true,\n origBoxes = boxes, // Original array will be altered with added .pos\n restBoxes = [], // The outranked overshoot\n box,\n target,\n total = 0;\n\n function sortByTarget(a, b) {\n return a.target - b.target;\n }\n\n // If the total size exceeds the len, remove those boxes with the lowest rank\n i = boxes.length;\n while (i--) {\n total += boxes[i].size;\n }\n\n // Sort by rank, then slice away overshoot\n if (total > len) {\n stableSort(boxes, function(a, b) {\n return (b.rank || 0) - (a.rank || 0);\n });\n i = 0;\n total = 0;\n while (total <= len) {\n total += boxes[i].size;\n i++;\n }\n restBoxes = boxes.splice(i - 1, boxes.length);\n }\n\n // Order by target\n stableSort(boxes, sortByTarget);\n\n\n // So far we have been mutating the original array. Now\n // create a copy with target arrays\n boxes = map(boxes, function(box) {\n return {\n size: box.size,\n targets: [box.target]\n };\n });\n\n while (overlapping) {\n // Initial positions: target centered in box\n i = boxes.length;\n while (i--) {\n box = boxes[i];\n // Composite box, average of targets\n target = (Math.min.apply(0, box.targets) + Math.max.apply(0, box.targets)) / 2;\n box.pos = Math.min(Math.max(0, target - box.size / 2), len - box.size);\n }\n\n // Detect overlap and join boxes\n i = boxes.length;\n overlapping = false;\n while (i--) {\n if (i > 0 && boxes[i - 1].pos + boxes[i - 1].size > boxes[i].pos) { // Overlap\n boxes[i - 1].size += boxes[i].size; // Add this size to the previous box\n boxes[i - 1].targets = boxes[i - 1].targets.concat(boxes[i].targets);\n\n // Overlapping right, push left\n if (boxes[i - 1].pos + boxes[i - 1].size > len) {\n boxes[i - 1].pos = len - boxes[i - 1].size;\n }\n boxes.splice(i, 1); // Remove this item\n overlapping = true;\n }\n }\n }\n\n // Now the composite boxes are placed, we need to put the original boxes within them\n i = 0;\n each(boxes, function(box) {\n var posInCompositeBox = 0;\n each(box.targets, function() {\n origBoxes[i].pos = box.pos + posInCompositeBox;\n posInCompositeBox += origBoxes[i].size;\n i++;\n });\n });\n\n // Add the rest (hidden) boxes and sort by target\n origBoxes.push.apply(origBoxes, restBoxes);\n stableSort(origBoxes, sortByTarget);\n };\n\n\n /**\n * Draw the data labels\n */\n Series.prototype.drawDataLabels = function() {\n var series = this,\n seriesOptions = series.options,\n options = seriesOptions.dataLabels,\n points = series.points,\n pointOptions,\n generalOptions,\n hasRendered = series.hasRendered || 0,\n str,\n dataLabelsGroup,\n defer = pick(options.defer, !!seriesOptions.animation),\n renderer = series.chart.renderer;\n\n if (options.enabled || series._hasPointLabels) {\n\n // Process default alignment of data labels for columns\n if (series.dlProcessOptions) {\n series.dlProcessOptions(options);\n }\n\n // Create a separate group for the data labels to avoid rotation\n dataLabelsGroup = series.plotGroup(\n 'dataLabelsGroup',\n 'data-labels',\n defer && !hasRendered ? 'hidden' : 'visible', // #5133\n options.zIndex || 6\n );\n\n if (defer) {\n dataLabelsGroup.attr({\n opacity: +hasRendered\n }); // #3300\n if (!hasRendered) {\n addEvent(series, 'afterAnimate', function() {\n if (series.visible) { // #2597, #3023, #3024\n dataLabelsGroup.show(true);\n }\n dataLabelsGroup[seriesOptions.animation ? 'animate' : 'attr']({\n opacity: 1\n }, {\n duration: 200\n });\n });\n }\n }\n\n // Make the labels for each point\n generalOptions = options;\n each(points, function(point) {\n var enabled,\n dataLabel = point.dataLabel,\n labelConfig,\n attr,\n rotation,\n connector = point.connector,\n isNew = !dataLabel,\n style;\n // Determine if each data label is enabled\n // @note dataLabelAttribs (like pointAttribs) would eradicate\n // the need for dlOptions, and simplify the section below.\n pointOptions = point.dlOptions || (point.options && point.options.dataLabels); // dlOptions is used in treemaps\n enabled = pick(pointOptions && pointOptions.enabled, generalOptions.enabled) && point.y !== null; // #2282, #4641\n if (enabled) {\n // Create individual options structure that can be extended without\n // affecting others\n options = merge(generalOptions, pointOptions);\n labelConfig = point.getLabelConfig();\n str = options.format ?\n format(options.format, labelConfig) :\n options.formatter.call(labelConfig, options);\n style = options.style;\n rotation = options.rotation;\n\n // Determine the color\n style.color = pick(options.color, style.color, series.color, '#000000');\n // Get automated contrast color\n if (style.color === 'contrast') {\n point.contrastColor = renderer.getContrast(point.color || series.color);\n style.color = options.inside || pick(point.labelDistance, options.distance) < 0 ||\n !!seriesOptions.stacking ? point.contrastColor : '#000000';\n }\n if (seriesOptions.cursor) {\n style.cursor = seriesOptions.cursor;\n }\n\n\n attr = {\n //align: align,\n\n fill: options.backgroundColor,\n stroke: options.borderColor,\n 'stroke-width': options.borderWidth,\n\n r: options.borderRadius || 0,\n rotation: rotation,\n padding: options.padding,\n zIndex: 1\n };\n\n // Remove unused attributes (#947)\n H.objectEach(attr, function(val, name) {\n if (val === undefined) {\n delete attr[name];\n }\n });\n }\n // If the point is outside the plot area, destroy it. #678, #820\n if (dataLabel && (!enabled || !defined(str))) {\n point.dataLabel = dataLabel = dataLabel.destroy();\n if (connector) {\n point.connector = connector.destroy();\n }\n // Individual labels are disabled if the are explicitly disabled\n // in the point options, or if they fall outside the plot area.\n } else if (enabled && defined(str)) {\n // create new label\n if (!dataLabel) {\n dataLabel = point.dataLabel = renderer[rotation ? 'text' : 'label']( // labels don't support rotation\n str,\n 0, -9999,\n options.shape,\n null,\n null,\n options.useHTML,\n null,\n 'data-label'\n );\n dataLabel.addClass(\n 'highcharts-data-label-color-' + point.colorIndex +\n ' ' + (options.className || '') +\n (options.useHTML ? 'highcharts-tracker' : '') // #3398\n );\n } else {\n attr.text = str;\n }\n dataLabel.attr(attr);\n\n // Styles must be applied before add in order to read text bounding box\n dataLabel.css(style).shadow(options.shadow);\n\n\n if (!dataLabel.added) {\n dataLabel.add(dataLabelsGroup);\n }\n // Now the data label is created and placed at 0,0, so we need to align it\n series.alignDataLabel(point, dataLabel, options, null, isNew);\n }\n });\n }\n };\n\n /**\n * Align each individual data label\n */\n Series.prototype.alignDataLabel = function(point, dataLabel, options, alignTo, isNew) {\n var chart = this.chart,\n inverted = chart.inverted,\n plotX = pick(point.plotX, -9999),\n plotY = pick(point.plotY, -9999),\n bBox = dataLabel.getBBox(),\n fontSize,\n baseline,\n rotation = options.rotation,\n normRotation,\n negRotation,\n align = options.align,\n rotCorr, // rotation correction\n // Math.round for rounding errors (#2683), alignTo to allow column labels (#2700)\n visible =\n this.visible &&\n (\n point.series.forceDL ||\n chart.isInsidePlot(plotX, Math.round(plotY), inverted) ||\n (\n alignTo && chart.isInsidePlot(\n plotX,\n inverted ? alignTo.x + 1 : alignTo.y + alignTo.height - 1,\n inverted\n )\n )\n ),\n alignAttr, // the final position;\n justify = pick(options.overflow, 'justify') === 'justify';\n\n if (visible) {\n\n\n fontSize = options.style.fontSize;\n\n\n baseline = chart.renderer.fontMetrics(fontSize, dataLabel).b;\n\n // The alignment box is a singular point\n alignTo = extend({\n x: inverted ? chart.plotWidth - plotY : plotX,\n y: Math.round(inverted ? chart.plotHeight - plotX : plotY),\n width: 0,\n height: 0\n }, alignTo);\n\n // Add the text size for alignment calculation\n extend(options, {\n width: bBox.width,\n height: bBox.height\n });\n\n // Allow a hook for changing alignment in the last moment, then do the alignment\n if (rotation) {\n justify = false; // Not supported for rotated text\n rotCorr = chart.renderer.rotCorr(baseline, rotation); // #3723\n alignAttr = {\n x: alignTo.x + options.x + alignTo.width / 2 + rotCorr.x,\n y: alignTo.y + options.y + {\n top: 0,\n middle: 0.5,\n bottom: 1\n }[options.verticalAlign] * alignTo.height\n };\n dataLabel[isNew ? 'attr' : 'animate'](alignAttr)\n .attr({ // #3003\n align: align\n });\n\n // Compensate for the rotated label sticking out on the sides\n normRotation = (rotation + 720) % 360;\n negRotation = normRotation > 180 && normRotation < 360;\n\n if (align === 'left') {\n alignAttr.y -= negRotation ? bBox.height : 0;\n } else if (align === 'center') {\n alignAttr.x -= bBox.width / 2;\n alignAttr.y -= bBox.height / 2;\n } else if (align === 'right') {\n alignAttr.x -= bBox.width;\n alignAttr.y -= negRotation ? 0 : bBox.height;\n }\n\n\n } else {\n dataLabel.align(options, null, alignTo);\n alignAttr = dataLabel.alignAttr;\n }\n\n // Handle justify or crop\n if (justify) {\n point.isLabelJustified = this.justifyDataLabel(\n dataLabel,\n options,\n alignAttr,\n bBox,\n alignTo,\n isNew\n );\n\n // Now check that the data label is within the plot area\n } else if (pick(options.crop, true)) {\n visible = chart.isInsidePlot(alignAttr.x, alignAttr.y) && chart.isInsidePlot(alignAttr.x + bBox.width, alignAttr.y + bBox.height);\n }\n\n // When we're using a shape, make it possible with a connector or an arrow pointing to thie point\n if (options.shape && !rotation) {\n dataLabel[isNew ? 'attr' : 'animate']({\n anchorX: inverted ? chart.plotWidth - point.plotY : point.plotX,\n anchorY: inverted ? chart.plotHeight - point.plotX : point.plotY\n });\n }\n }\n\n // Show or hide based on the final aligned position\n if (!visible) {\n dataLabel.attr({\n y: -9999\n });\n dataLabel.placed = false; // don't animate back in\n }\n\n };\n\n /**\n * If data labels fall partly outside the plot area, align them back in, in a way that\n * doesn't hide the point.\n */\n Series.prototype.justifyDataLabel = function(dataLabel, options, alignAttr, bBox, alignTo, isNew) {\n var chart = this.chart,\n align = options.align,\n verticalAlign = options.verticalAlign,\n off,\n justified,\n padding = dataLabel.box ? 0 : (dataLabel.padding || 0);\n\n // Off left\n off = alignAttr.x + padding;\n if (off < 0) {\n if (align === 'right') {\n options.align = 'left';\n } else {\n options.x = -off;\n }\n justified = true;\n }\n\n // Off right\n off = alignAttr.x + bBox.width - padding;\n if (off > chart.plotWidth) {\n if (align === 'left') {\n options.align = 'right';\n } else {\n options.x = chart.plotWidth - off;\n }\n justified = true;\n }\n\n // Off top\n off = alignAttr.y + padding;\n if (off < 0) {\n if (verticalAlign === 'bottom') {\n options.verticalAlign = 'top';\n } else {\n options.y = -off;\n }\n justified = true;\n }\n\n // Off bottom\n off = alignAttr.y + bBox.height - padding;\n if (off > chart.plotHeight) {\n if (verticalAlign === 'top') {\n options.verticalAlign = 'bottom';\n } else {\n options.y = chart.plotHeight - off;\n }\n justified = true;\n }\n\n if (justified) {\n dataLabel.placed = !isNew;\n dataLabel.align(options, null, alignTo);\n }\n\n return justified;\n };\n\n /**\n * Override the base drawDataLabels method by pie specific functionality\n */\n if (seriesTypes.pie) {\n seriesTypes.pie.prototype.drawDataLabels = function() {\n var series = this,\n data = series.data,\n point,\n chart = series.chart,\n options = series.options.dataLabels,\n connectorPadding = pick(options.connectorPadding, 10),\n connectorWidth = pick(options.connectorWidth, 1),\n plotWidth = chart.plotWidth,\n plotHeight = chart.plotHeight,\n connector,\n seriesCenter = series.center,\n radius = seriesCenter[2] / 2,\n centerY = seriesCenter[1],\n dataLabel,\n dataLabelWidth,\n labelPos,\n labelHeight,\n halves = [ // divide the points into right and left halves for anti collision\n [], // right\n [] // left\n ],\n x,\n y,\n visibility,\n j,\n overflow = [0, 0, 0, 0]; // top, right, bottom, left\n\n // get out if not enabled\n if (!series.visible || (!options.enabled && !series._hasPointLabels)) {\n return;\n }\n\n // Reset all labels that have been shortened\n each(data, function(point) {\n if (point.dataLabel && point.visible && point.dataLabel.shortened) {\n point.dataLabel\n .attr({\n width: 'auto'\n }).css({\n width: 'auto',\n textOverflow: 'clip'\n });\n point.dataLabel.shortened = false;\n }\n });\n\n\n // run parent method\n Series.prototype.drawDataLabels.apply(series);\n\n each(data, function(point) {\n if (point.dataLabel && point.visible) { // #407, #2510\n\n // Arrange points for detection collision\n halves[point.half].push(point);\n\n // Reset positions (#4905)\n point.dataLabel._pos = null;\n }\n });\n\n /* Loop over the points in each half, starting from the top and bottom\n * of the pie to detect overlapping labels.\n */\n each(halves, function(points, i) {\n\n var top,\n bottom,\n length = points.length,\n positions = [],\n naturalY,\n sideOverflow,\n positionsIndex, // Point index in positions array.\n size;\n\n if (!length) {\n return;\n }\n\n // Sort by angle\n series.sortByAngle(points, i - 0.5);\n // Only do anti-collision when we have dataLabels outside the pie \n // and have connectors. (#856)\n if (series.maxLabelDistance > 0) {\n top = Math.max(\n 0,\n centerY - radius - series.maxLabelDistance\n );\n bottom = Math.min(\n centerY + radius + series.maxLabelDistance,\n chart.plotHeight\n );\n each(points, function(point) {\n // check if specific points' label is outside the pie\n if (point.labelDistance > 0 && point.dataLabel) {\n // point.top depends on point.labelDistance value\n // Used for calculation of y value in getX method \n point.top = Math.max(\n 0,\n centerY - radius - point.labelDistance\n );\n point.bottom = Math.min(\n centerY + radius + point.labelDistance,\n chart.plotHeight\n );\n size = point.dataLabel.getBBox().height || 21;\n\n // point.positionsIndex is needed for getting index of \n // parameter related to specific point inside positions \n // array - not every point is in positions array.\n point.positionsIndex = positions.push({\n target: point.labelPos[1] - point.top + size / 2,\n size: size,\n rank: point.y\n }) - 1;\n }\n });\n H.distribute(positions, bottom + size - top);\n }\n\n // Now the used slots are sorted, fill them up sequentially\n for (j = 0; j < length; j++) {\n\n point = points[j];\n positionsIndex = point.positionsIndex;\n labelPos = point.labelPos;\n dataLabel = point.dataLabel;\n visibility = point.visible === false ? 'hidden' : 'inherit';\n naturalY = labelPos[1];\n\n if (positions && defined(positions[positionsIndex])) {\n if (positions[positionsIndex].pos === undefined) {\n visibility = 'hidden';\n } else {\n labelHeight = positions[positionsIndex].size;\n y = point.top + positions[positionsIndex].pos;\n }\n\n } else {\n y = naturalY;\n }\n\n // It is needed to delete point.positionIndex for \n // dynamically added points etc.\n\n delete point.positionIndex;\n\n // get the x - use the natural x position for labels near the \n // top and bottom, to prevent the top and botton slice connectors \n // from touching each other on either side\n if (options.justify) {\n x = seriesCenter[0] + (i ? -1 : 1) * (radius + point.labelDistance);\n } else {\n x = series.getX(y < point.top + 2 || y > point.bottom - 2 ? naturalY : y, i, point);\n }\n\n\n // Record the placement and visibility\n dataLabel._attr = {\n visibility: visibility,\n align: labelPos[6]\n };\n dataLabel._pos = {\n x: x + options.x +\n ({\n left: connectorPadding,\n right: -connectorPadding\n }[labelPos[6]] || 0),\n y: y + options.y - 10 // 10 is for the baseline (label vs text)\n };\n labelPos.x = x;\n labelPos.y = y;\n\n\n // Detect overflowing data labels\n dataLabelWidth = dataLabel.getBBox().width;\n\n sideOverflow = null;\n // Overflow left\n if (x - dataLabelWidth < connectorPadding) {\n sideOverflow = Math.round(\n dataLabelWidth - x + connectorPadding\n );\n overflow[3] = Math.max(sideOverflow, overflow[3]);\n\n // Overflow right\n } else if (x + dataLabelWidth > plotWidth - connectorPadding) {\n sideOverflow = Math.round(\n x + dataLabelWidth - plotWidth + connectorPadding\n );\n overflow[1] = Math.max(sideOverflow, overflow[1]);\n }\n\n // Overflow top\n if (y - labelHeight / 2 < 0) {\n overflow[0] = Math.max(\n Math.round(-y + labelHeight / 2),\n overflow[0]\n );\n\n // Overflow left\n } else if (y + labelHeight / 2 > plotHeight) {\n overflow[2] = Math.max(\n Math.round(y + labelHeight / 2 - plotHeight),\n overflow[2]\n );\n }\n dataLabel.sideOverflow = sideOverflow;\n } // for each point\n }); // for each half\n\n // Do not apply the final placement and draw the connectors until we have verified\n // that labels are not spilling over.\n if (arrayMax(overflow) === 0 || this.verifyDataLabelOverflow(overflow)) {\n\n // Place the labels in the final position\n this.placeDataLabels();\n\n // Draw the connectors\n if (connectorWidth) {\n each(this.points, function(point) {\n var isNew;\n\n connector = point.connector;\n dataLabel = point.dataLabel;\n\n if (\n dataLabel &&\n dataLabel._pos &&\n point.visible &&\n point.labelDistance > 0\n ) {\n visibility = dataLabel._attr.visibility;\n\n isNew = !connector;\n\n if (isNew) {\n point.connector = connector = chart.renderer.path()\n .addClass('highcharts-data-label-connector highcharts-color-' + point.colorIndex)\n .add(series.dataLabelsGroup);\n\n\n connector.attr({\n 'stroke-width': connectorWidth,\n 'stroke': options.connectorColor || point.color || '#666666'\n });\n\n }\n connector[isNew ? 'attr' : 'animate']({\n d: series.connectorPath(point.labelPos)\n });\n connector.attr('visibility', visibility);\n\n } else if (connector) {\n point.connector = connector.destroy();\n }\n });\n }\n }\n };\n\n /**\n * Extendable method for getting the path of the connector between the data label\n * and the pie slice.\n */\n seriesTypes.pie.prototype.connectorPath = function(labelPos) {\n var x = labelPos.x,\n y = labelPos.y;\n return pick(this.options.dataLabels.softConnector, true) ? [\n 'M',\n x + (labelPos[6] === 'left' ? 5 : -5), y, // end of the string at the label\n 'C',\n x, y, // first break, next to the label\n 2 * labelPos[2] - labelPos[4], 2 * labelPos[3] - labelPos[5],\n labelPos[2], labelPos[3], // second break\n 'L',\n labelPos[4], labelPos[5] // base\n ] : [\n 'M',\n x + (labelPos[6] === 'left' ? 5 : -5), y, // end of the string at the label\n 'L',\n labelPos[2], labelPos[3], // second break\n 'L',\n labelPos[4], labelPos[5] // base\n ];\n };\n\n /**\n * Perform the final placement of the data labels after we have verified that they\n * fall within the plot area.\n */\n seriesTypes.pie.prototype.placeDataLabels = function() {\n each(this.points, function(point) {\n var dataLabel = point.dataLabel,\n _pos;\n if (dataLabel && point.visible) {\n _pos = dataLabel._pos;\n if (_pos) {\n\n // Shorten data labels with ellipsis if they still overflow\n // after the pie has reached minSize (#223).\n if (dataLabel.sideOverflow) {\n dataLabel._attr.width =\n dataLabel.getBBox().width - dataLabel.sideOverflow;\n dataLabel.css({\n width: dataLabel._attr.width + 'px',\n textOverflow: 'ellipsis'\n });\n dataLabel.shortened = true;\n }\n\n dataLabel.attr(dataLabel._attr);\n dataLabel[dataLabel.moved ? 'animate' : 'attr'](_pos);\n dataLabel.moved = true;\n } else if (dataLabel) {\n dataLabel.attr({\n y: -9999\n });\n }\n }\n }, this);\n };\n\n seriesTypes.pie.prototype.alignDataLabel = noop;\n\n /**\n * Verify whether the data labels are allowed to draw, or we should run more translation and data\n * label positioning to keep them inside the plot area. Returns true when data labels are ready\n * to draw.\n */\n seriesTypes.pie.prototype.verifyDataLabelOverflow = function(overflow) {\n\n var center = this.center,\n options = this.options,\n centerOption = options.center,\n minSize = options.minSize || 80,\n newSize = minSize,\n // If a size is set, return true and don't try to shrink the pie\n // to fit the labels.\n ret = options.size !== null;\n\n if (!ret) {\n // Handle horizontal size and center\n if (centerOption[0] !== null) { // Fixed center\n newSize = Math.max(center[2] -\n Math.max(overflow[1], overflow[3]), minSize);\n\n } else { // Auto center\n newSize = Math.max(\n // horizontal overflow\n center[2] - overflow[1] - overflow[3],\n minSize\n );\n // horizontal center\n center[0] += (overflow[3] - overflow[1]) / 2;\n }\n\n // Handle vertical size and center\n if (centerOption[1] !== null) { // Fixed center\n newSize = Math.max(Math.min(newSize, center[2] -\n Math.max(overflow[0], overflow[2])), minSize);\n\n } else { // Auto center\n newSize = Math.max(\n Math.min(\n newSize,\n // vertical overflow\n center[2] - overflow[0] - overflow[2]\n ),\n minSize\n );\n // vertical center\n center[1] += (overflow[0] - overflow[2]) / 2;\n }\n\n // If the size must be decreased, we need to run translate and\n // drawDataLabels again\n if (newSize < center[2]) {\n center[2] = newSize;\n center[3] = Math.min( // #3632\n relativeLength(options.innerSize || 0, newSize),\n newSize\n );\n this.translate(center);\n\n if (this.drawDataLabels) {\n this.drawDataLabels();\n }\n // Else, return true to indicate that the pie and its labels is\n // within the plot area\n } else {\n ret = true;\n }\n }\n return ret;\n };\n }\n\n if (seriesTypes.column) {\n\n /**\n * Override the basic data label alignment by adjusting for the position of the column\n */\n seriesTypes.column.prototype.alignDataLabel = function(point, dataLabel, options, alignTo, isNew) {\n var inverted = this.chart.inverted,\n series = point.series,\n dlBox = point.dlBox || point.shapeArgs, // data label box for alignment\n below = pick(point.below, point.plotY > pick(this.translatedThreshold, series.yAxis.len)), // point.below is used in range series\n inside = pick(options.inside, !!this.options.stacking), // draw it inside the box?\n overshoot;\n\n // Align to the column itself, or the top of it\n if (dlBox) { // Area range uses this method but not alignTo\n alignTo = merge(dlBox);\n\n if (alignTo.y < 0) {\n alignTo.height += alignTo.y;\n alignTo.y = 0;\n }\n overshoot = alignTo.y + alignTo.height - series.yAxis.len;\n if (overshoot > 0) {\n alignTo.height -= overshoot;\n }\n\n if (inverted) {\n alignTo = {\n x: series.yAxis.len - alignTo.y - alignTo.height,\n y: series.xAxis.len - alignTo.x - alignTo.width,\n width: alignTo.height,\n height: alignTo.width\n };\n }\n\n // Compute the alignment box\n if (!inside) {\n if (inverted) {\n alignTo.x += below ? 0 : alignTo.width;\n alignTo.width = 0;\n } else {\n alignTo.y += below ? alignTo.height : 0;\n alignTo.height = 0;\n }\n }\n }\n\n\n // When alignment is undefined (typically columns and bars), display the individual\n // point below or above the point depending on the threshold\n options.align = pick(\n options.align, !inverted || inside ? 'center' : below ? 'right' : 'left'\n );\n options.verticalAlign = pick(\n options.verticalAlign,\n inverted || inside ? 'middle' : below ? 'top' : 'bottom'\n );\n\n // Call the parent method\n Series.prototype.alignDataLabel.call(this, point, dataLabel, options, alignTo, isNew);\n\n // If label was justified and we have contrast, set it:\n if (point.isLabelJustified && point.contrastColor) {\n point.dataLabel.css({\n color: point.contrastColor\n });\n }\n };\n }\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2009-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n /**\n * Highcharts module to hide overlapping data labels. This module is included in\n * Highcharts.\n */\n var Chart = H.Chart,\n each = H.each,\n pick = H.pick,\n addEvent = H.addEvent;\n\n // Collect potensial overlapping data labels. Stack labels probably don't need\n // to be considered because they are usually accompanied by data labels that lie\n // inside the columns.\n Chart.prototype.callbacks.push(function(chart) {\n function collectAndHide() {\n var labels = [];\n\n each(chart.series || [], function(series) {\n var dlOptions = series.options.dataLabels,\n // Range series have two collections\n collections = series.dataLabelCollections || ['dataLabel'];\n\n if (\n (dlOptions.enabled || series._hasPointLabels) &&\n !dlOptions.allowOverlap &&\n series.visible\n ) { // #3866\n each(collections, function(coll) {\n each(series.points, function(point) {\n if (point[coll]) {\n point[coll].labelrank = pick(\n point.labelrank,\n point.shapeArgs && point.shapeArgs.height\n ); // #4118\n labels.push(point[coll]);\n }\n });\n });\n }\n });\n chart.hideOverlappingLabels(labels);\n }\n\n // Do it now ...\n collectAndHide();\n\n // ... and after each chart redraw\n addEvent(chart, 'redraw', collectAndHide);\n\n });\n\n /**\n * Hide overlapping labels. Labels are moved and faded in and out on zoom to\n * provide a smooth visual imression.\n */\n Chart.prototype.hideOverlappingLabels = function(labels) {\n\n var len = labels.length,\n label,\n i,\n j,\n label1,\n label2,\n isIntersecting,\n pos1,\n pos2,\n parent1,\n parent2,\n padding,\n intersectRect = function(x1, y1, w1, h1, x2, y2, w2, h2) {\n return !(\n x2 > x1 + w1 ||\n x2 + w2 < x1 ||\n y2 > y1 + h1 ||\n y2 + h2 < y1\n );\n };\n\n // Mark with initial opacity\n for (i = 0; i < len; i++) {\n label = labels[i];\n if (label) {\n label.oldOpacity = label.opacity;\n label.newOpacity = 1;\n }\n }\n\n // Prevent a situation in a gradually rising slope, that each label will\n // hide the previous one because the previous one always has lower rank.\n labels.sort(function(a, b) {\n return (b.labelrank || 0) - (a.labelrank || 0);\n });\n\n // Detect overlapping labels\n for (i = 0; i < len; i++) {\n label1 = labels[i];\n\n for (j = i + 1; j < len; ++j) {\n label2 = labels[j];\n if (\n label1 && label2 &&\n label1 !== label2 && // #6465, polar chart with connectEnds\n label1.placed && label2.placed &&\n label1.newOpacity !== 0 && label2.newOpacity !== 0\n ) {\n pos1 = label1.alignAttr;\n pos2 = label2.alignAttr;\n // Different panes have different positions\n parent1 = label1.parentGroup;\n parent2 = label2.parentGroup;\n // Substract the padding if no background or border (#4333)\n padding = 2 * (label1.box ? 0 : label1.padding);\n isIntersecting = intersectRect(\n pos1.x + parent1.translateX,\n pos1.y + parent1.translateY,\n label1.width - padding,\n label1.height - padding,\n pos2.x + parent2.translateX,\n pos2.y + parent2.translateY,\n label2.width - padding,\n label2.height - padding\n );\n\n if (isIntersecting) {\n (label1.labelrank < label2.labelrank ? label1 : label2)\n .newOpacity = 0;\n }\n }\n }\n }\n\n // Hide or show\n each(labels, function(label) {\n var complete,\n newOpacity;\n\n if (label) {\n newOpacity = label.newOpacity;\n\n if (label.oldOpacity !== newOpacity && label.placed) {\n\n // Make sure the label is completely hidden to avoid catching\n // clicks (#4362)\n if (newOpacity) {\n label.show(true);\n } else {\n complete = function() {\n label.hide();\n };\n }\n\n // Animate or set the opacity \n label.alignAttr.opacity = newOpacity;\n label[label.isOld ? 'animate' : 'attr'](\n label.alignAttr,\n null,\n complete\n );\n\n }\n label.isOld = true;\n }\n });\n };\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var addEvent = H.addEvent,\n Chart = H.Chart,\n createElement = H.createElement,\n css = H.css,\n defaultOptions = H.defaultOptions,\n defaultPlotOptions = H.defaultPlotOptions,\n each = H.each,\n extend = H.extend,\n fireEvent = H.fireEvent,\n hasTouch = H.hasTouch,\n inArray = H.inArray,\n isObject = H.isObject,\n Legend = H.Legend,\n merge = H.merge,\n pick = H.pick,\n Point = H.Point,\n Series = H.Series,\n seriesTypes = H.seriesTypes,\n svg = H.svg,\n TrackerMixin;\n\n /**\n * TrackerMixin for points and graphs.\n *\n * @mixin\n */\n TrackerMixin = H.TrackerMixin = {\n\n /**\n * Draw the tracker for a point.\n */\n drawTrackerPoint: function() {\n var series = this,\n chart = series.chart,\n pointer = chart.pointer,\n onMouseOver = function(e) {\n var point = pointer.getPointFromEvent(e);\n // undefined on graph in scatterchart\n if (point !== undefined) {\n pointer.isDirectTouch = true;\n point.onMouseOver(e);\n }\n };\n\n // Add reference to the point\n each(series.points, function(point) {\n if (point.graphic) {\n point.graphic.element.point = point;\n }\n if (point.dataLabel) {\n if (point.dataLabel.div) {\n point.dataLabel.div.point = point;\n } else {\n point.dataLabel.element.point = point;\n }\n }\n });\n\n // Add the event listeners, we need to do this only once\n if (!series._hasTracking) {\n each(series.trackerGroups, function(key) {\n if (series[key]) { // we don't always have dataLabelsGroup\n series[key]\n .addClass('highcharts-tracker')\n .on('mouseover', onMouseOver)\n .on('mouseout', function(e) {\n pointer.onTrackerMouseOut(e);\n });\n if (hasTouch) {\n series[key].on('touchstart', onMouseOver);\n }\n\n\n if (series.options.cursor) {\n series[key]\n .css(css)\n .css({\n cursor: series.options.cursor\n });\n }\n\n }\n });\n series._hasTracking = true;\n }\n },\n\n /**\n * Draw the tracker object that sits above all data labels and markers to\n * track mouse events on the graph or points. For the line type charts\n * the tracker uses the same graphPath, but with a greater stroke width\n * for better control.\n */\n drawTrackerGraph: function() {\n var series = this,\n options = series.options,\n trackByArea = options.trackByArea,\n trackerPath = [].concat(trackByArea ? series.areaPath : series.graphPath),\n trackerPathLength = trackerPath.length,\n chart = series.chart,\n pointer = chart.pointer,\n renderer = chart.renderer,\n snap = chart.options.tooltip.snap,\n tracker = series.tracker,\n i,\n onMouseOver = function() {\n if (chart.hoverSeries !== series) {\n series.onMouseOver();\n }\n },\n /*\n * Empirical lowest possible opacities for TRACKER_FILL for an element to stay invisible but clickable\n * IE6: 0.002\n * IE7: 0.002\n * IE8: 0.002\n * IE9: 0.00000000001 (unlimited)\n * IE10: 0.0001 (exporting only)\n * FF: 0.00000000001 (unlimited)\n * Chrome: 0.000001\n * Safari: 0.000001\n * Opera: 0.00000000001 (unlimited)\n */\n TRACKER_FILL = 'rgba(192,192,192,' + (svg ? 0.0001 : 0.002) + ')';\n\n // Extend end points. A better way would be to use round linecaps,\n // but those are not clickable in VML.\n if (trackerPathLength && !trackByArea) {\n i = trackerPathLength + 1;\n while (i--) {\n if (trackerPath[i] === 'M') { // extend left side\n trackerPath.splice(i + 1, 0, trackerPath[i + 1] - snap, trackerPath[i + 2], 'L');\n }\n if ((i && trackerPath[i] === 'M') || i === trackerPathLength) { // extend right side\n trackerPath.splice(i, 0, 'L', trackerPath[i - 2] + snap, trackerPath[i - 1]);\n }\n }\n }\n\n // handle single points\n /*for (i = 0; i < singlePoints.length; i++) {\n singlePoint = singlePoints[i];\n trackerPath.push(M, singlePoint.plotX - snap, singlePoint.plotY,\n L, singlePoint.plotX + snap, singlePoint.plotY);\n }*/\n\n // draw the tracker\n if (tracker) {\n tracker.attr({\n d: trackerPath\n });\n } else if (series.graph) { // create\n\n series.tracker = renderer.path(trackerPath)\n .attr({\n 'stroke-linejoin': 'round', // #1225\n visibility: series.visible ? 'visible' : 'hidden',\n stroke: TRACKER_FILL,\n fill: trackByArea ? TRACKER_FILL : 'none',\n 'stroke-width': series.graph.strokeWidth() + (trackByArea ? 0 : 2 * snap),\n zIndex: 2\n })\n .add(series.group);\n\n // The tracker is added to the series group, which is clipped, but is covered\n // by the marker group. So the marker group also needs to capture events.\n each([series.tracker, series.markerGroup], function(tracker) {\n tracker.addClass('highcharts-tracker')\n .on('mouseover', onMouseOver)\n .on('mouseout', function(e) {\n pointer.onTrackerMouseOut(e);\n });\n\n\n if (options.cursor) {\n tracker.css({\n cursor: options.cursor\n });\n }\n\n\n if (hasTouch) {\n tracker.on('touchstart', onMouseOver);\n }\n });\n }\n }\n };\n /* End TrackerMixin */\n\n\n /**\n * Add tracking event listener to the series group, so the point graphics\n * themselves act as trackers\n */\n\n if (seriesTypes.column) {\n seriesTypes.column.prototype.drawTracker = TrackerMixin.drawTrackerPoint;\n }\n\n if (seriesTypes.pie) {\n seriesTypes.pie.prototype.drawTracker = TrackerMixin.drawTrackerPoint;\n }\n\n if (seriesTypes.scatter) {\n seriesTypes.scatter.prototype.drawTracker = TrackerMixin.drawTrackerPoint;\n }\n\n /*\n * Extend Legend for item events\n */\n extend(Legend.prototype, {\n\n setItemEvents: function(item, legendItem, useHTML) {\n var legend = this,\n boxWrapper = legend.chart.renderer.boxWrapper,\n activeClass = 'highcharts-legend-' + (item.series ? 'point' : 'series') + '-active';\n\n // Set the events on the item group, or in case of useHTML, the item itself (#1249)\n (useHTML ? legendItem : item.legendGroup).on('mouseover', function() {\n item.setState('hover');\n\n // A CSS class to dim or hide other than the hovered series\n boxWrapper.addClass(activeClass);\n\n\n legendItem.css(legend.options.itemHoverStyle);\n\n })\n .on('mouseout', function() {\n\n legendItem.css(merge(item.visible ? legend.itemStyle : legend.itemHiddenStyle));\n\n\n // A CSS class to dim or hide other than the hovered series\n boxWrapper.removeClass(activeClass);\n\n item.setState();\n })\n .on('click', function(event) {\n var strLegendItemClick = 'legendItemClick',\n fnLegendItemClick = function() {\n if (item.setVisible) {\n item.setVisible();\n }\n };\n\n // Pass over the click/touch event. #4.\n event = {\n browserEvent: event\n };\n\n // click the name or symbol\n if (item.firePointEvent) { // point\n item.firePointEvent(strLegendItemClick, event, fnLegendItemClick);\n } else {\n fireEvent(item, strLegendItemClick, event, fnLegendItemClick);\n }\n });\n },\n\n createCheckboxForItem: function(item) {\n var legend = this;\n\n item.checkbox = createElement('input', {\n type: 'checkbox',\n checked: item.selected,\n defaultChecked: item.selected // required by IE7\n }, legend.options.itemCheckboxStyle, legend.chart.container);\n\n addEvent(item.checkbox, 'click', function(event) {\n var target = event.target;\n fireEvent(\n item.series || item,\n 'checkboxClick', { // #3712\n checked: target.checked,\n item: item\n },\n function() {\n item.select();\n }\n );\n });\n }\n });\n\n\n\n // Add pointer cursor to legend itemstyle in defaultOptions\n defaultOptions.legend.itemStyle.cursor = 'pointer';\n\n\n\n /*\n * Extend the Chart object with interaction\n */\n\n extend(Chart.prototype, /** @lends Chart.prototype */ {\n /**\n * Display the zoom button\n */\n showResetZoom: function() {\n var chart = this,\n lang = defaultOptions.lang,\n btnOptions = chart.options.chart.resetZoomButton,\n theme = btnOptions.theme,\n states = theme.states,\n alignTo = btnOptions.relativeTo === 'chart' ? null : 'plotBox';\n\n function zoomOut() {\n chart.zoomOut();\n }\n\n this.resetZoomButton = chart.renderer.button(lang.resetZoom, null, null, zoomOut, theme, states && states.hover)\n .attr({\n align: btnOptions.position.align,\n title: lang.resetZoomTitle\n })\n .addClass('highcharts-reset-zoom')\n .add()\n .align(btnOptions.position, false, alignTo);\n\n },\n\n /**\n * Zoom out to 1:1\n */\n zoomOut: function() {\n var chart = this;\n fireEvent(chart, 'selection', {\n resetSelection: true\n }, function() {\n chart.zoom();\n });\n },\n\n /**\n * Zoom into a given portion of the chart given by axis coordinates\n * @param {Object} event\n */\n zoom: function(event) {\n var chart = this,\n hasZoomed,\n pointer = chart.pointer,\n displayButton = false,\n resetZoomButton;\n\n // If zoom is called with no arguments, reset the axes\n if (!event || event.resetSelection) {\n each(chart.axes, function(axis) {\n hasZoomed = axis.zoom();\n });\n } else { // else, zoom in on all axes\n each(event.xAxis.concat(event.yAxis), function(axisData) {\n var axis = axisData.axis,\n isXAxis = axis.isXAxis;\n\n // don't zoom more than minRange\n if (pointer[isXAxis ? 'zoomX' : 'zoomY']) {\n hasZoomed = axis.zoom(axisData.min, axisData.max);\n if (axis.displayBtn) {\n displayButton = true;\n }\n }\n });\n }\n\n // Show or hide the Reset zoom button\n resetZoomButton = chart.resetZoomButton;\n if (displayButton && !resetZoomButton) {\n chart.showResetZoom();\n } else if (!displayButton && isObject(resetZoomButton)) {\n chart.resetZoomButton = resetZoomButton.destroy();\n }\n\n\n // Redraw\n if (hasZoomed) {\n chart.redraw(\n pick(chart.options.chart.animation, event && event.animation, chart.pointCount < 100) // animation\n );\n }\n },\n\n /**\n * Pan the chart by dragging the mouse across the pane. This function is called\n * on mouse move, and the distance to pan is computed from chartX compared to\n * the first chartX position in the dragging operation.\n */\n pan: function(e, panning) {\n\n var chart = this,\n hoverPoints = chart.hoverPoints,\n doRedraw;\n\n // remove active points for shared tooltip\n if (hoverPoints) {\n each(hoverPoints, function(point) {\n point.setState();\n });\n }\n\n each(panning === 'xy' ? [1, 0] : [1], function(isX) { // xy is used in maps\n var axis = chart[isX ? 'xAxis' : 'yAxis'][0],\n horiz = axis.horiz,\n mousePos = e[horiz ? 'chartX' : 'chartY'],\n mouseDown = horiz ? 'mouseDownX' : 'mouseDownY',\n startPos = chart[mouseDown],\n halfPointRange = (axis.pointRange || 0) / 2,\n extremes = axis.getExtremes(),\n panMin = axis.toValue(startPos - mousePos, true) +\n halfPointRange,\n panMax = axis.toValue(startPos + axis.len - mousePos, true) -\n halfPointRange,\n flipped = panMax < panMin,\n newMin = flipped ? panMax : panMin,\n newMax = flipped ? panMin : panMax,\n paddedMin = Math.min(\n extremes.dataMin,\n axis.toValue(\n axis.toPixels(extremes.min) - axis.minPixelPadding\n )\n ),\n paddedMax = Math.max(\n extremes.dataMax,\n axis.toValue(\n axis.toPixels(extremes.max) + axis.minPixelPadding\n )\n ),\n spill;\n\n // If the new range spills over, either to the min or max, adjust\n // the new range.\n spill = paddedMin - newMin;\n if (spill > 0) {\n newMax += spill;\n newMin = paddedMin;\n }\n spill = newMax - paddedMax;\n if (spill > 0) {\n newMax = paddedMax;\n newMin -= spill;\n }\n\n // Set new extremes if they are actually new\n if (axis.series.length && newMin !== extremes.min && newMax !== extremes.max) {\n axis.setExtremes(\n newMin,\n newMax,\n false,\n false, {\n trigger: 'pan'\n }\n );\n doRedraw = true;\n }\n\n chart[mouseDown] = mousePos; // set new reference for next run\n });\n\n if (doRedraw) {\n chart.redraw(false);\n }\n css(chart.container, {\n cursor: 'move'\n });\n }\n });\n\n /*\n * Extend the Point object with interaction\n */\n extend(Point.prototype, /** @lends Highcharts.Point.prototype */ {\n /**\n * Toggle the selection status of a point.\n * @param {Boolean} [selected]\n * When `true`, the point is selected. When `false`, the point is\n * unselected. When `null` or `undefined`, the selection state is\n * toggled.\n * @param {Boolean} [accumulate=false]\n * When `true`, the selection is added to other selected points.\n * When `false`, other selected points are deselected. Internally in\n * Highcharts, when {@link http://api.highcharts.com/highcharts/plotOptions.series.allowPointSelect|allowPointSelect}\n * is `true`, selected points are accumulated on Control, Shift or\n * Cmd clicking the point.\n *\n * @see Highcharts.Chart#getSelectedPoints\n *\n * @sample highcharts/members/point-select/\n * Select a point from a button\n * @sample highcharts/chart/events-selection-points/\n * Select a range of points through a drag selection\n * @sample maps/series/data-id/\n * Select a point in Highmaps\n */\n select: function(selected, accumulate) {\n var point = this,\n series = point.series,\n chart = series.chart;\n\n selected = pick(selected, !point.selected);\n\n // fire the event with the default handler\n point.firePointEvent(selected ? 'select' : 'unselect', {\n accumulate: accumulate\n }, function() {\n\n /**\n * Whether the point is selected or not. \n * @see Highcharts.Point#select\n * @memberof Highcharts.Point\n * @name selected\n * @type {Boolean}\n */\n point.selected = point.options.selected = selected;\n series.options.data[inArray(point, series.data)] = point.options;\n\n point.setState(selected && 'select');\n\n // unselect all other points unless Ctrl or Cmd + click\n if (!accumulate) {\n each(chart.getSelectedPoints(), function(loopPoint) {\n if (loopPoint.selected && loopPoint !== point) {\n loopPoint.selected = loopPoint.options.selected = false;\n series.options.data[inArray(loopPoint, series.data)] = loopPoint.options;\n loopPoint.setState('');\n loopPoint.firePointEvent('unselect');\n }\n });\n }\n });\n },\n\n /**\n * Runs on mouse over the point\n * \n * @param {Object} e The event arguments\n */\n onMouseOver: function(e) {\n var point = this,\n series = point.series,\n chart = series.chart,\n pointer = chart.pointer;\n e = e ?\n pointer.normalize(e) :\n // In cases where onMouseOver is called directly without an event\n pointer.getChartCoordinatesFromPoint(point, chart.inverted);\n pointer.runPointActions(e, point);\n },\n\n /**\n * Runs on mouse out from the point\n */\n onMouseOut: function() {\n var point = this,\n chart = point.series.chart;\n point.firePointEvent('mouseOut');\n each(chart.hoverPoints || [], function(p) {\n p.setState();\n });\n chart.hoverPoints = chart.hoverPoint = null;\n },\n\n /**\n * Import events from the series' and point's options. Only do it on\n * demand, to save processing time on hovering.\n */\n importEvents: function() {\n if (!this.hasImportedEvents) {\n var point = this,\n options = merge(point.series.options.point, point.options),\n events = options.events;\n\n point.events = events;\n\n H.objectEach(events, function(event, eventType) {\n addEvent(point, eventType, event);\n });\n this.hasImportedEvents = true;\n\n }\n },\n\n /**\n * Set the point's state\n * @param {String} state\n */\n setState: function(state, move) {\n var point = this,\n plotX = Math.floor(point.plotX), // #4586\n plotY = point.plotY,\n series = point.series,\n stateOptions = series.options.states[state] || {},\n markerOptions = defaultPlotOptions[series.type].marker &&\n series.options.marker,\n normalDisabled = markerOptions && markerOptions.enabled === false,\n markerStateOptions = (markerOptions && markerOptions.states &&\n markerOptions.states[state]) || {},\n stateDisabled = markerStateOptions.enabled === false,\n stateMarkerGraphic = series.stateMarkerGraphic,\n pointMarker = point.marker || {},\n chart = series.chart,\n halo = series.halo,\n haloOptions,\n markerAttribs,\n hasMarkers = markerOptions && series.markerAttribs,\n newSymbol;\n\n state = state || ''; // empty string\n\n if (\n // already has this state\n (state === point.state && !move) ||\n // selected points don't respond to hover\n (point.selected && state !== 'select') ||\n // series' state options is disabled\n (stateOptions.enabled === false) ||\n // general point marker's state options is disabled\n (state && (stateDisabled || (normalDisabled && markerStateOptions.enabled === false))) ||\n // individual point marker's state options is disabled\n (state && pointMarker.states && pointMarker.states[state] && pointMarker.states[state].enabled === false) // #1610\n\n ) {\n return;\n }\n\n if (hasMarkers) {\n markerAttribs = series.markerAttribs(point, state);\n }\n\n // Apply hover styles to the existing point\n if (point.graphic) {\n\n if (point.state) {\n point.graphic.removeClass('highcharts-point-' + point.state);\n }\n if (state) {\n point.graphic.addClass('highcharts-point-' + state);\n }\n\n /*attribs = radius ? { // new symbol attributes (#507, #612)\n x: plotX - radius,\n y: plotY - radius,\n width: 2 * radius,\n height: 2 * radius\n } : {};*/\n\n\n //attribs = merge(series.pointAttribs(point, state), attribs);\n point.graphic.attr(series.pointAttribs(point, state));\n\n\n if (markerAttribs) {\n point.graphic.animate(\n markerAttribs,\n pick(\n chart.options.chart.animation, // Turn off globally\n markerStateOptions.animation,\n markerOptions.animation\n )\n );\n }\n\n // Zooming in from a range with no markers to a range with markers\n if (stateMarkerGraphic) {\n stateMarkerGraphic.hide();\n }\n } else {\n // if a graphic is not applied to each point in the normal state, create a shared\n // graphic for the hover state\n if (state && markerStateOptions) {\n newSymbol = pointMarker.symbol || series.symbol;\n\n // If the point has another symbol than the previous one, throw away the\n // state marker graphic and force a new one (#1459)\n if (stateMarkerGraphic && stateMarkerGraphic.currentSymbol !== newSymbol) {\n stateMarkerGraphic = stateMarkerGraphic.destroy();\n }\n\n // Add a new state marker graphic\n if (!stateMarkerGraphic) {\n if (newSymbol) {\n series.stateMarkerGraphic = stateMarkerGraphic = chart.renderer.symbol(\n newSymbol,\n markerAttribs.x,\n markerAttribs.y,\n markerAttribs.width,\n markerAttribs.height\n )\n .add(series.markerGroup);\n stateMarkerGraphic.currentSymbol = newSymbol;\n }\n\n // Move the existing graphic\n } else {\n stateMarkerGraphic[move ? 'animate' : 'attr']({ // #1054\n x: markerAttribs.x,\n y: markerAttribs.y\n });\n }\n\n if (stateMarkerGraphic) {\n stateMarkerGraphic.attr(series.pointAttribs(point, state));\n }\n\n }\n\n if (stateMarkerGraphic) {\n stateMarkerGraphic[state && chart.isInsidePlot(plotX, plotY, chart.inverted) ? 'show' : 'hide'](); // #2450\n stateMarkerGraphic.element.point = point; // #4310\n }\n }\n\n // Show me your halo\n haloOptions = stateOptions.halo;\n if (haloOptions && haloOptions.size) {\n if (!halo) {\n series.halo = halo = chart.renderer.path()\n // #5818, #5903, #6705\n .add((point.graphic || stateMarkerGraphic).parentGroup);\n }\n halo[move ? 'animate' : 'attr']({\n d: point.haloPath(haloOptions.size)\n });\n halo.attr({\n 'class': 'highcharts-halo highcharts-color-' +\n pick(point.colorIndex, series.colorIndex)\n });\n halo.point = point; // #6055\n\n\n halo.attr(extend({\n 'fill': point.color || series.color,\n 'fill-opacity': haloOptions.opacity,\n 'zIndex': -1 // #4929, IE8 added halo above everything\n }, haloOptions.attributes));\n\n\n } else if (halo && halo.point && halo.point.haloPath) {\n // Animate back to 0 on the current halo point (#6055)\n halo.animate({\n d: halo.point.haloPath(0)\n });\n }\n\n point.state = state;\n },\n\n /**\n * Get the circular path definition for the halo\n * @param {Number} size The radius of the circular halo.\n * @returns {Array} The path definition\n */\n haloPath: function(size) {\n var series = this.series,\n chart = series.chart;\n\n return chart.renderer.symbols.circle(\n Math.floor(this.plotX) - size,\n this.plotY - size,\n size * 2,\n size * 2\n );\n }\n });\n\n /*\n * Extend the Series object with interaction\n */\n\n extend(Series.prototype, /** @lends Highcharts.Series.prototype */ {\n /**\n * Series mouse over handler\n */\n onMouseOver: function() {\n var series = this,\n chart = series.chart,\n hoverSeries = chart.hoverSeries;\n\n // set normal state to previous series\n if (hoverSeries && hoverSeries !== series) {\n hoverSeries.onMouseOut();\n }\n\n // trigger the event, but to save processing time,\n // only if defined\n if (series.options.events.mouseOver) {\n fireEvent(series, 'mouseOver');\n }\n\n // hover this\n series.setState('hover');\n chart.hoverSeries = series;\n },\n\n /**\n * Series mouse out handler\n */\n onMouseOut: function() {\n // trigger the event only if listeners exist\n var series = this,\n options = series.options,\n chart = series.chart,\n tooltip = chart.tooltip,\n hoverPoint = chart.hoverPoint;\n\n chart.hoverSeries = null; // #182, set to null before the mouseOut event fires\n\n // trigger mouse out on the point, which must be in this series\n if (hoverPoint) {\n hoverPoint.onMouseOut();\n }\n\n // fire the mouse out event\n if (series && options.events.mouseOut) {\n fireEvent(series, 'mouseOut');\n }\n\n\n // hide the tooltip\n if (tooltip && !series.stickyTracking && (!tooltip.shared || series.noSharedTooltip)) {\n tooltip.hide();\n }\n\n // set normal state\n series.setState();\n },\n\n /**\n * Set the state of the graph\n */\n setState: function(state) {\n var series = this,\n options = series.options,\n graph = series.graph,\n stateOptions = options.states,\n lineWidth = options.lineWidth,\n attribs,\n i = 0;\n\n state = state || '';\n\n if (series.state !== state) {\n\n // Toggle class names\n each([\n series.group,\n series.markerGroup,\n series.dataLabelsGroup\n ], function(group) {\n if (group) {\n // Old state\n if (series.state) {\n group.removeClass('highcharts-series-' + series.state);\n }\n // New state\n if (state) {\n group.addClass('highcharts-series-' + state);\n }\n }\n });\n\n series.state = state;\n\n\n\n if (stateOptions[state] && stateOptions[state].enabled === false) {\n return;\n }\n\n if (state) {\n lineWidth = stateOptions[state].lineWidth || lineWidth + (stateOptions[state].lineWidthPlus || 0); // #4035\n }\n\n if (graph && !graph.dashstyle) { // hover is turned off for dashed lines in VML\n attribs = {\n 'stroke-width': lineWidth\n };\n\n // Animate the graph stroke-width. By default a quick animation\n // to hover, slower to un-hover.\n graph.animate(\n attribs,\n pick(\n series.chart.options.chart.animation,\n stateOptions[state] && stateOptions[state].animation\n )\n );\n while (series['zone-graph-' + i]) {\n series['zone-graph-' + i].attr(attribs);\n i = i + 1;\n }\n }\n\n }\n },\n\n /**\n * Show or hide the series.\n *\n * @param {Boolean} [visible]\n * True to show the series, false to hide. If undefined, the\n * visibility is toggled.\n * @param {Boolean} [redraw=true]\n * Whether to redraw the chart after the series is altered. If doing\n * more operations on the chart, it is a good idea to set redraw to\n * false and call {@link Chart#redraw|chart.redraw()} after.\n */\n setVisible: function(vis, redraw) {\n var series = this,\n chart = series.chart,\n legendItem = series.legendItem,\n showOrHide,\n ignoreHiddenSeries = chart.options.chart.ignoreHiddenSeries,\n oldVisibility = series.visible;\n\n // if called without an argument, toggle visibility\n series.visible = vis = series.options.visible = series.userOptions.visible = vis === undefined ? !oldVisibility : vis; // #5618\n showOrHide = vis ? 'show' : 'hide';\n\n // show or hide elements\n each(['group', 'dataLabelsGroup', 'markerGroup', 'tracker', 'tt'], function(key) {\n if (series[key]) {\n series[key][showOrHide]();\n }\n });\n\n\n // hide tooltip (#1361)\n if (chart.hoverSeries === series || (chart.hoverPoint && chart.hoverPoint.series) === series) {\n series.onMouseOut();\n }\n\n\n if (legendItem) {\n chart.legend.colorizeItem(series, vis);\n }\n\n\n // rescale or adapt to resized chart\n series.isDirty = true;\n // in a stack, all other series are affected\n if (series.options.stacking) {\n each(chart.series, function(otherSeries) {\n if (otherSeries.options.stacking && otherSeries.visible) {\n otherSeries.isDirty = true;\n }\n });\n }\n\n // show or hide linked series\n each(series.linkedSeries, function(otherSeries) {\n otherSeries.setVisible(vis, false);\n });\n\n if (ignoreHiddenSeries) {\n chart.isDirtyBox = true;\n }\n if (redraw !== false) {\n chart.redraw();\n }\n\n fireEvent(series, showOrHide);\n },\n\n /**\n * Show the series if hidden.\n *\n * @sample highcharts/members/series-hide/\n * Toggle visibility from a button\n */\n show: function() {\n this.setVisible(true);\n },\n\n /**\n * Hide the series if visible. If the {@link\n * https://api.highcharts.com/highcharts/chart.ignoreHiddenSeries|\n * chart.ignoreHiddenSeries} option is true, the chart is redrawn without\n * this series.\n *\n * @sample highcharts/members/series-hide/\n * Toggle visibility from a button\n */\n hide: function() {\n this.setVisible(false);\n },\n\n\n /**\n * Select or unselect the series. This means its {@link\n * Highcharts.Series.selected|selected} property is set, the checkbox in the\n * legend is toggled and when selected, the series is returned by the\n * {@link Highcharts.Chart#getSelectedSeries} function.\n *\n * @param {Boolean} [selected]\n * True to select the series, false to unselect. If undefined, the\n * selection state is toggled.\n *\n * @sample highcharts/members/series-select/\n * Select a series from a button\n */\n select: function(selected) {\n var series = this;\n\n series.selected = selected = (selected === undefined) ?\n !series.selected :\n selected;\n\n if (series.checkbox) {\n series.checkbox.checked = selected;\n }\n\n fireEvent(series, selected ? 'select' : 'unselect');\n },\n\n drawTracker: TrackerMixin.drawTrackerGraph\n });\n\n }(Highcharts));\n (function(H) {\n /**\n * (c) 2010-2017 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */\n var Chart = H.Chart,\n each = H.each,\n inArray = H.inArray,\n isArray = H.isArray,\n isObject = H.isObject,\n pick = H.pick,\n splat = H.splat;\n\n /**\n * Update the chart based on the current chart/document size and options for\n * responsiveness.\n */\n Chart.prototype.setResponsive = function(redraw) {\n var options = this.options.responsive,\n ruleIds = [],\n currentResponsive = this.currentResponsive,\n currentRuleIds;\n\n if (options && options.rules) {\n each(options.rules, function(rule) {\n if (rule._id === undefined) {\n rule._id = H.uniqueKey();\n }\n\n this.matchResponsiveRule(rule, ruleIds, redraw);\n }, this);\n }\n\n // Merge matching rules\n var mergedOptions = H.merge.apply(0, H.map(ruleIds, function(ruleId) {\n return H.find(options.rules, function(rule) {\n return rule._id === ruleId;\n }).chartOptions;\n }));\n\n // Stringified key for the rules that currently apply.\n ruleIds = ruleIds.toString() || undefined;\n currentRuleIds = currentResponsive && currentResponsive.ruleIds;\n\n\n // Changes in what rules apply\n if (ruleIds !== currentRuleIds) {\n\n // Undo previous rules. Before we apply a new set of rules, we need to\n // roll back completely to base options (#6291).\n if (currentResponsive) {\n this.update(currentResponsive.undoOptions, redraw);\n }\n\n if (ruleIds) {\n // Get undo-options for matching rules\n this.currentResponsive = {\n ruleIds: ruleIds,\n mergedOptions: mergedOptions,\n undoOptions: this.currentOptions(mergedOptions)\n };\n\n this.update(mergedOptions, redraw);\n\n } else {\n this.currentResponsive = undefined;\n }\n }\n };\n\n /**\n * Handle a single responsiveness rule\n */\n Chart.prototype.matchResponsiveRule = function(rule, matches) {\n var condition = rule.condition,\n fn = condition.callback || function() {\n return this.chartWidth <= pick(condition.maxWidth, Number.MAX_VALUE) &&\n this.chartHeight <= pick(condition.maxHeight, Number.MAX_VALUE) &&\n this.chartWidth >= pick(condition.minWidth, 0) &&\n this.chartHeight >= pick(condition.minHeight, 0);\n };\n\n if (fn.call(this)) {\n matches.push(rule._id);\n }\n\n };\n\n /**\n * Get the current values for a given set of options. Used before we update\n * the chart with a new responsiveness rule.\n * TODO: Restore axis options (by id?)\n */\n Chart.prototype.currentOptions = function(options) {\n\n var ret = {};\n\n /**\n * Recurse over a set of options and its current values,\n * and store the current values in the ret object.\n */\n function getCurrent(options, curr, ret, depth) {\n var i;\n H.objectEach(options, function(val, key) {\n if (!depth && inArray(key, ['series', 'xAxis', 'yAxis']) > -1) {\n options[key] = splat(options[key]);\n\n ret[key] = [];\n\n // Iterate over collections like series, xAxis or yAxis and map\n // the items by index.\n for (i = 0; i < options[key].length; i++) {\n if (curr[key][i]) { // Item exists in current data (#6347)\n ret[key][i] = {};\n getCurrent(\n val[i],\n curr[key][i],\n ret[key][i],\n depth + 1\n );\n }\n }\n } else if (isObject(val)) {\n ret[key] = isArray(val) ? [] : {};\n getCurrent(val, curr[key] || {}, ret[key], depth + 1);\n } else {\n ret[key] = curr[key] || null;\n }\n });\n }\n\n getCurrent(options, this.options, ret, 0);\n return ret;\n };\n\n }(Highcharts));\n return Highcharts\n }));\n});\n"],"sourceRoot":""}