{"version":3,"sources":["Config.js","BarVizRouter.js","highcharts.src.js","DataResponseModel.js","BarView.js","HeaderView.js","NoBarDataView.js","SelectorsView.js"],"names":["ns","window","nspace","Config","dataUrl","defaultHighchartsConfig","chart","type","marginRight","colors","linearGradient","x1","x2","y0","y1","stops","credits","enabled","title","text","yAxis","opposite","gridLineWidth","labels","style","font-family","font-size","color","lineWidth","lineColor","xAxis","gridLineColor","tickLength","tickInterval","plotOptions","bar","dataLabels","crop","overflow","format","groupPadding","pointPadding","events","legendItemClick","legend","align","borderRadius","borderColor","borderWidth","verticalAlign","layout","useHTML","width","backgroundColor","itemStyle","cursor","labelFormatter","labelFormatterHelper","this","name","words","str","charCount","i","split","length","push","join","reversed","tooltip","headerFormat","pointFormat","followPointer","SingleCharacteristicConfig","sharedNs","BarVizRouter","routers","VizRouterBase","extend","routes","",":indicatorId",":indicatorId/:characteristicIds",":indicatorId/:characteristicIds/:locationIds",":indicatorId/:characteristicIds/:locationIds/:dataFormatId",":indicatorId/:characteristicIds/:locationIds/:dataFormatId/:timeFrameId","initializeViews","indicatorId","characteristicIds","locationIds","dataFormatId","timeFrameId","getValue","raw","selectorsModel","models","SelectorsModel","set","getArrayFromModelProperty","silent","dataModel","DataResponseModel","dispatcher","ccc","viz","config","views","loadingSpinner","LoadingSpinnerView","sourceDefinitionNotesView","SourceDefinitionNotesView","model","selectorsView","SelectorsView","indicatorGroupId","selectorData","vizType","barView","BarView","el","headerView","HeaderView","noBarDataView","NoBarDataView","completeRouterInitialization","routeUrlParts","get","getStringFromArrayProperty","_","noop","UNDEFINED","Renderer","garbageBin","defaultOptions","dateFormat","globalAnimation","pathAnim","timeUnits","makeTime","getMinutes","getHours","getDay","getDate","getMonth","getFullYear","setMinutes","setHours","setDate","setMonth","setFullYear","$","doc","document","win","math","Math","mathRound","round","mathFloor","floor","mathCeil","ceil","mathMax","max","mathMin","min","mathAbs","abs","mathCos","cos","mathSin","sin","mathPI","PI","deg2rad","userAgent","navigator","isOpera","opera","isIE","test","docMode8","documentMode","isWebKit","isFirefox","isTouchDevice","SVG_NS","hasSVG","createElementNS","createSVGRect","hasBidiBug","parseInt","useCanVG","createElement","getContext","hasTouch","documentElement","ontouchstart","symbolSizes","idCounter","charts","PRODUCT","DIV","ABSOLUTE","RELATIVE","HIDDEN","PREFIX","VISIBLE","PX","NONE","M","L","TRACKER_FILL","HOVER_STATE","SELECT_STATE","MILLISECOND","SECOND","MINUTE","HOUR","DAY","WEEK","MONTH","YEAR","STROKE_WIDTH","seriesTypes","a","b","n","merge","doCopy","copy","original","value","key","_typeof","hasOwnProperty","Object","prototype","toString","call","nodeType","len","arguments","ret","pInt","s","mag","isString","isObject","obj","isArray","isNumber","log2lin","num","log","LN10","lin2log","pow","erase","arr","item","splice","defined","attr","elem","prop","setAttribute","getAttribute","splat","pick","arg","args","css","styles","opacity","filter","tag","attribs","parent","nopad","padding","border","margin","appendChild","extendClass","members","object","numberFormat","number","decimals","decPoint","thousandsSep","lang","c","isNaN","d","undefined","decimalPoint","t","String","toFixed","j","substr","replace","slice","pad","Array","wrap","method","func","proceed","unshift","apply","ctx","segment","valueAndFormat","path","val","index","splitter","isInside","indexOf","shift","match","getMagnitude","normalizeTickInterval","interval","multiples","magnitude","options","normalized","allowDecimals","normalizeTimeTickInterval","unitsOption","units","unit","unitRange","count","unitName","getTimeTicks","normalizedInterval","startOfWeek","minYear","tickPositions","higherRanks","useUTC","global","minDate","Date","setMilliseconds","setSeconds","getSeconds","time","getTime","minMonth","minDateDate","timezoneOffset","getTimezoneOffset","each","grep","info","totalRange","ChartCounters","symbol","stableSort","sortFunction","sortValue","ss_i","sort","arrayMin","data","arrayMax","destroyObjectProperties","except","destroy","discardElement","element","innerHTML","error","code","stop","msg","console","correctFloat","parseFloat","toPrecision","setAnimation","animation","Highcharts","timestamp","capitalize","date","hours","day","dayOfMonth","month","fullYear","langWeekdays","weekdays","replacements","A","e","shortMonths","B","months","m","y","Y","H","I","l","p","P","S","dateFormats","toUpperCase","wrapColor","wrapSymbol","hash","init","fromD","toD","sixify","endLength","startBaseLine","endBaseLine","bezier","numParams","start","end","concat","isArea","step","pos","complete","startVal","jQuery","HighchartsAdapter","dSetter","Fx","fx","Step","Tween","propHooks","opacityHook","cssHooks","easing","easeOutQuad","x","fn","base","now","computed","ends","started","forEach","highcharts","constr","renderTo","getScript","inArray","adapterRun","map","results","offset","addEvent","event","bind","removeEvent","eventType","handler","removeEventListener","unbind","fireEvent","eventArguments","defaultFunction","defaultPrevented","Event","detachedType","layerX","layerY","trigger","isDefaultPrevented","washMouseEvent","originalEvent","pageX","pageY","animate","params","$el","globalAdapter","adapter","defaultLabelOptions","fontSize","lineHeight","defaultPlotOptions","symbols","loading","numericSymbols","resetZoom","resetZoomTitle","canvasToolsURL","VMLRadialGradientURL","defaultSeriesType","ignoreHiddenSeries","spacing","fontFamily","plotBorderColor","resetZoomButton","theme","zIndex","position","subtitle","line","allowPointSelect","showCheckbox","duration","marker","radius","states","hover","select","fillColor","point","formatter","cropThreshold","pointRange","stickyTracking","navigation","activeColor","inactiveColor","shadow","itemHoverStyle","itemHiddenStyle","itemCheckboxStyle","height","symbolWidth","symbolPadding","fontWeight","labelStyle","top","textAlign","dateTimeLabelFormats","millisecond","second","minute","hour","week","year","snap","whiteSpace","href","defaultSeriesOptions","setTimeMethods","GET","SET","UTC","minutes","seconds","Color","input","result","rgba","rgbaRegEx","exec","hexRegEx","rgbRegEx","brighten","alpha","setOpacity","SVGElement","renderer","nodeName","attrSetters","animOptions","child","skipAttr","titleNode","hasSetSymbolSize","doTransform","wrapper","toLowerCase","shadows","childNodes","rotation","rx","ry","left","center","right","getElementsByTagName","textContent","stroke","hasStroke","removeAttribute","symbolName","symbolAttr","cutHeight","textStr","bBox","added","buildText","updateTransform","addClass","className","currentClassName","clip","clipRect","url","id","crisp","strokeWidth","normalizer","values","hyphenate","elemWrapper","textWidth","serializedCss","fill","on","svgElement","touchEventFired","preventDefault","onclick","setRadialReference","coordinates","radialReference","translate","translateX","translateY","invert","inverted","htmlCss","tagName","htmlGetBBox","offsetLeft","offsetTop","offsetWidth","offsetHeight","htmlUpdateTransform","alignCorrection","nonLeft","marginLeft","marginTop","invertChild","baseline","quad","radians","costheta","sintheta","xCorr","yCorr","currentTextTransform","cTT","setSpanRotation","elemWidth","elemHeight","innerText","display","fontMetrics","alignOnAdd","rotationStyle","transform","scaleX","scaleY","toFront","parentNode","alignOptions","alignByTranslate","box","vAlign","alignTo","alignedObjects","bottom","middle","placed","alignAttr","getBBox","rad","namespaceURI","forExport","isSVG","show","visibility","hide","fadeOut","add","otherElement","otherZIndex","inserted","parentWrapper","parentGroup","parentInverted","handleZ","insertBefore","safeRemoveChild","removeChild","grandParent","parentToClean","onmouseout","onmouseover","onmousemove","clipPath","div","shadowOptions","group","cutOff","shadowWidth","shadowElementOpacity","offsetX","offsetY","cloneNode","isShadow","stroke-opacity","stroke-width","SVGRenderer","VMLRenderer","VMLElement","CanVGRenderer","CanVGController","deferredRenderCalls","Element","container","boxWrapper","subPixelFix","rect","loc","location","version","createTextNode","defs","gradients","setSize","getBoundingClientRect","isHidden","rendererDefs","draw","textNode","lines","styleRegex","hrefRegex","parentX","textStyles","textLineHeight","pop","lineNo","spans","spanNo","span","spanStyle","attributes","tspan","dx","h","actualWidth","clipHeight","_clipHeight","rest","dy","softLineNo","measureSpanWidth","firstChild","button","callback","normalState","hoverState","pressedState","disabledState","shape","stateOptions","stateStyle","normalStyle","hoverStyle","pressedStyle","disabledStyle","label","curState","STYLE","verticalGradient","y2","r","setState","state","crispLine","points","circle","arc","innerR","g","class","image","src","preserveAspectRatio","setAttributeNS","imageSrc","imageSize","centerImage","symbolFn","imageRegex","img","size","isImg","onload","w","cpw","square","triangle","triangle-down","diamond","innerRadius","open","cosStart","sinStart","cosEnd","sinEnd","longArc","colorObject","gradName","gradAttr","gradientObject","stopColor","stopOpacity","regexRgba","radialGradient","gradientUnits","cx","cy","stopObject","stop-color","stop-opacity","defaultChartStyle","fakeSVG","html","svgGroupWrapper","htmlGroup","parents","reverse","htmlGroupStyle","anchorX","anchorY","wrapperX","wrapperY","baselineOffset","needsBox","alignFactor","paddingLeft","crispAdjust","deferredAttr","updateBoxSize","boxX","boxY","updateTextPadding","boxAttr","getSizeAfterAdd","baseCss","markup","isDiv","prepVML","deferUpdateTransform","pathToVML","clockwise","isArc","elemStyle","strokeweight","cutOffPath","updateClipping","stroked","dashstyle","filled","clipMembers","cssRet","destroyClip","getCSS","evt","target","srcElement","modifiedPath","cssText","VMLRendererExtension","isIE8","isVML","namespaces","hcv","createStyleSheet","styleSheets","isObj","isShape","member","fillType","opacity1","opacity2","color1","color2","firstStop","lastStop","gradient","fillAttr","addFillNode","atan","sizex","sizey","applyRadialGradient","propNodes","vmlStyle","coordsize","isCircle","parentStyle","flip","drawDeferred","callIndex","callLength","Tick","axis","noLabel","isNew","addLabel","PlotLineOrBand","StackItem","isNegative","stackOption","stacking","total","stack","percent","Axis","Tooltip","Pointer","Legend","Chart","measuringSpan","scriptLocation","dateTimeLabelFormat","tick","horiz","categories","names","labelOptions","staggerLines","plotWidth","chartWidth","isFirst","isLast","tickPositionInfo","isDatetimeAxis","isLog","labelAlign","ellipsis","labelGroup","getLabelSize","labelBBox","getLabelSides","leftSide","handleOverflow","xy","sides","rightSide","plotLeft","plotRight","neighbour","ticks","neighbourEdge","getPosition","tickmarkOffset","old","cHeight","oldChartHeight","chartHeight","transB","oldChartWidth","getLabelPosition","transA","side","labelOffset","getMarkPath","tickWidth","render","gridLinePath","markPath","gridLine","gridPrefix","tickPrefix","dashStyle","tickColor","tickPosition","mark","reverseCrisp","isActive","getPlotLinePath","gridGroup","axisGroup","showFirstLabel","showLastLabel","xs","ys","plotLine","halfPointRange","optionsLabel","to","from","isBand","svgElem","getPlotBandPath","onGetPath","plotLinesAndBands","endOnTick","formatOption","setOffset","xOffset","xWidth","neg","yZero","plotHeight","stackBox","isInsidePlot","minPadding","maxPadding","minorGridLineColor","minorGridLineWidth","minorTickColor","minorTickLength","minorTickPosition","startOnTick","tickmarkPlacement","tickPixelInterval","defaultYAxisOptions","stackLabels","defaultLeftAxisOptions","defaultRightAxisOptions","defaultBottomAxisOptions","defaultTopAxisOptions","userOptions","isXAxis","isX","xOrY","setOptions","defaultLabelFormatter","minPixelPadding","zoomEnabled","isLinked","linkedTo","minorTicks","alternateBands","minRange","userMinRange","maxZoom","range","stacks","oldStacks","stackExtremes","axes","series","removePlotBand","removePlotBandOrLine","removePlotLine","val2lin","lin2val","update","newOptions","redraw","_addedPlotLB","userMin","userMax","isDirtyBox","remove","multi","numericSymbolDetector","getSeriesExtremes","hasVisibleSeries","dataMin","dataMax","buildStacks","visible","xData","seriesDataMin","seriesDataMax","threshold","getExtremes","ignoreMinPadding","ignoreMaxPadding","backwards","cvsCoord","handleLog","pointPlacement","returnValue","axisLength","sign","cvsOffset","localA","oldTransA","localMin","oldMin","postTranslate","ordinal","toPixels","paneCoordinates","toValue","pixel","force","skip","axisLeft","axisTop","translatedValue","cWidth","toPath","getLinearTickPositions","lastPos","roundedMin","roundedMax","getLogTickPositions","minor","positions","_minorAutoInterval","intermediate","break2","realMin","realMax","tickIntervalOption","filteredTickIntervalOption","tickPixelIntervalOption","totalPixelLength","getMinorTickPositions","minorTickInterval","minorTickPositions","adjustForMinRange","zoomOffset","closestDataRange","distance","loopLength","minArgs","maxArgs","spaceAvailable","xIncrement","setAxisTranslation","saveOld","closestPointRange","ordinalCorrection","minPointOffset","pointRangePadding","linkedParent","seriesPointRange","seriesClosestPointRange","noSharedTooltip","ordinalSlope","translationSlope","setTickPositions","secondPass","linkedParentExtremes","keepTwoTicksOnly","tickPositioner","minTickIntervalOption","minTickInterval","beforePadding","usePercentage","isRadial","processData","oldMax","beforeSetTickPositions","postProcessTickInterval","ordinalPositions","getNonLinearTimeTicks","setMaxTicks","maxTicks","_maxTicksKey","alignTicks","adjustTickAmount","tickAmount","oldTickAmount","calculatedTickAmount","isDirty","setScale","isDirtyData","isDirtyAxisLength","oldAxisLength","setAxisSize","forceRedraw","oldUserMin","oldUserMax","cum","setExtremes","newMin","newMax","eventArgs","isDirtyExtremes","zoom","allowZoomOutside","displayBtn","offsetRight","plotTop","getThreshold","addPlotBand","addPlotBandOrLine","addPlotLine","coll","autoLabelAlign","angle","getOffset","hasData","showAxis","titleOffsetOption","sortedPositions","lastRight","overlap","invertedSide","titleOffset","titleMargin","axisTitleOptions","axisOffset","clipOffset","directionFactor","autoStaggerLines","maxStaggerLines","showEmpty","gridZIndex","1","3","axisTitle","low","high","axisTitleMargin","getLinePath","lineLeft","lineTop","getTitlePosition","alongAxis","offAxis","linePath","stackLabelOptions","alternateGridColor","slideInTicks","hasRendered","plotLines","plotBands","plotLineOptions","destroyInactiveItems","forDestruction","delay","setTimeout","axisLine","stackKey","oneStack","stackCategory","stackTotalGroup","setTitle","newTitleOptions","pointer","reset","setStackedPoints","setPercentStacks","setCategories","keepEvents","crosshairs","shared","crosshair","clearTimeout","hideTimer","tooltipTimeout","move","hoverPoints","hideDelay","hideCrosshairs","getAnchor","mouseEvent","plotX","plotY","tooltipPos","chartX","normalize","chartY","plotLow","plotHigh","boxWidth","boxHeight","alignedRight","pointX","pointY","defaultFormatter","items","tooltipHeaderFormatter","tooltipFormatter","tooltipOptions","footerFormat","refresh","anchor","currentSeries","textConfig","pointConfig","crosshairsOptions","getLabelConfig","category","updatePosition","stackY","modifyValue","positioner","zoomX","zoomY","chartOptions","chartEvents","zoomType","zoomHor","zoomVert","runChartClick","click","pinchDown","lastValidTouch","setDOMEvents","chartPosition","ePos","touches","clientX","getCoordinates","getIndex","runPointActions","hoverPoint","hoverSeries","enableMouseTracking","tooltipPoints","_dist","hoverX","tracker","onMouseOver","allowMove","onMouseOut","scaleGroups","seriesAttribs","getPlotBox","markerGroup","dataLabelsGroup","clipBox","pinchTranslate","selectionMarker","pinchTranslateDirection","forcedScale","singleTouch","touch0Start","touch1Start","scale","touch0Now","touch1Now","clipXY","plotLeftTop","selectionWH","selectionXY","outOfBounds","transformScale","scaleKey","XY","sChartXY","wh","bounds","pinch","self","followTouchMove","touchesLength","pinchHor","pinchVert","hasZoom","fireClickEvent","inClass","runTrackerClick","absMin","absMax","plotBox","hasPinched","dragStart","mouseIsDown","cancelClick","mouseDownX","mouseDownY","drag","clickedInside","hasDragged","sqrt","hasCartesianSeries","selectionMarkerFill","panning","pan","drop","runZoom","selectionData","selectionBox","selectionLeft","selectionTop","selectionMin","selectionMax","_cursor","onContainerMouseDown","onDocumentMouseUp","onDocumentMouseMove","onContainerMouseLeave","onContainerMouseMove","openMenu","elemClassName","onTrackerMouseOut","toElement","relatedTarget","onContainerClick","cancelBubble","firePointEvent","onContainerTouchStart","onContainerTouchMove","onDocumentTouchEnd","_events","eventConfig","clearInterval","itemMarginTop","initialItemX","initialItemY","maxItemWidth","itemHeight","lastLineHeight","positionCheckboxes","colorizeItem","legendItem","legendLine","legendSymbol","hiddenColor","textColor","symbolColor","markerOptions","isMarker","convertAttribs","positionItem","ltr","rtl","legendItemPos","_legendItemPos","itemX","itemY","checkbox","legendGroup","legendWidth","destroyItem","scrollOffset","legendHeight","allItems","legendItemWidth","renderTitle","titleOptions","titleHeight","contentGroup","renderItem","itemWidth","horizontal","itemDistance","widthOption","itemMarginBottom","li","itemOptions","scrollGroup","drawLegendSymbol","labelFormat","fnLegendItemClick","setVisible","strLegendItemClick","browserEvent","checked","selected","defaultChecked","lastItemY","legendBorderWidth","legendBackgroundColor","serie","seriesOptions","showInLegend","legendItems","legendType","legendIndex","isResizing","optionsY","alignTop","spaceHeight","spacingBox","maxHeight","navOptions","arrowSize","nav","pageCount","currentPage","fullHeight","up","scroll","pager","down","scrollBy","runPositionItem","optionsChart","splashArray","v","showAxes","reflow","initReflow","pointCount","counters","firstRender","initSeries","addSeries","isDirtyLegend","linkSeries","addAxis","adjustTickAmounts","hasStackedSeries","hasDirtyStacks","redrawLegend","seriesLength","isHiddenChart","afterRedraw","cloneRenderTo","layOutTitles","getStacks","getMargins","drawChartBox","isCartesian","showLoading","loadingDiv","loadingOptions","loadingSpan","loadingShown","showDuration","hideLoading","hideDuration","getAxes","optionsArray","xAxisOptions","yAxisOptions","axisOptions","getSelectedPoints","getSelectedSeries","showResetZoom","btnOptions","relativeTo","zoomOut","resetSelection","hasZoomed","displayButton","axisData","doRedraw","mousePos","startPos","extremes","subtitleOptions","chartTitleOptions","chartSubtitleOptions","autoWidth","floating","getChartSize","renderToClone","containerWidth","containerHeight","revert","clone","body","getContainer","oldChartIndex","containerId","indexAttrName","getElementById","-webkit-tap-highlight-color","create","legendOptions","legendMargin","legendX","legendY","resetMargins","marginBottom","extraBottomMargin","extraTopMargin","setChartSize","reflowTimeout","hasUserSize","fireEndResize","skipAxes","clipX","clipY","plotBorderWidth","plotSizeX","plotSizeY","mgn","bgAttr","chartBackground","plotBackground","plotBorder","plotBGImage","chartBorderWidth","chartBackgroundColor","plotBackgroundColor","plotBackgroundImage","plotShadow","propFromSeries","klass","chartSeries","linkedSeries","creditsHref","seriesGroup","setTooltipPoints","isReadyToRender","readyState","canvg","attachEvent","detachEvent","serieOptions","callbacks","oVar","tArray","Point","applyOptions","pointAttr","colorByPoint","colorCounter","pointValKey","optionsToObject","autoIncrement","firstItemType","pointArrayMap","valueCount","_hasPointLabels","_hasPointMarkers","graphic","dataLabel","destroyElements","props","percentage","stackTotal","accumulate","loopPoint","seriesTooltipOptions","valueDecimals","valuePrefix","valueSuffix","getAttribs","yData","toYData","zData","z","fixedBox","importEvents","ctrlKey","metaKey","shiftKey","hasImportedEvents","newSymbol","normalDisabled","markerStateOptions","stateDisabled","stateMarkerGraphic","pointMarker","currentSymbol","Series","pointClass","sorted","requireSorting","pointAttrToOptions","bindAxes","getColor","getSymbol","setData","_i","AXIS","pointStart","pointInterval","getSegments","lastNull","segments","pointsLength","connectNulls","typeOptions","defaultColors","_colorIndex","symbolIndex","seriesMarkerOption","defaultSymbols","_symbolIndex","legendItemGroup","verticalCenter","addPoint","isInTheMiddle","graph","area","currentShift","dataOptions","graphNeg","areaNeg","generatePoints","oldData","firstPoint","pt","dataLength","turboThreshold","hasToYData","isRemoving","croppedData","cropped","processedXData","processedYData","cropStart","forceCrop","cropData","cropEnd","cropShoulder","processedDataLength","hasGroupedData","other","stackedYData","yDataLength","negKey","negStacks","pointExtremes","totalFactor","validValue","withinRange","activeYData","activeCounter","xExtremes","xMin","xMax","getExtremesFromAll","hasModifyValue","dynamicallyPlaced","pointStack","stackValues","xValue","yValue","yBottom","pointXOffset","barW","Infinity","negative","renew","nextPoint","tooltipLen","orderTooltipPoints","wrappedClientX","xDateFormat","isDateTime","mouseOver","mouseOut","markerClipRect","sharedClipKey","animationTimeout","afterAnimate","drawPoints","isImage","pointMarkerOptions","seriesMarkerOptions","base1","base2","base3","option","conversion","pointStateOptionsHover","hasPointSpecificOptions","normalOptions","stateOptionsHover","seriesColor","normalDefaults","seriesPointAttr","negativeColor","defaultLineColor","brightness","oldOptions","oldType","proto","issue134","drawDataLabels","pointOptions","generalOptions","dlProcessOptions","plotGroup","labelConfig","connector","alignDataLabel","justifyDataLabel","off","justified","getSegmentPath","segmentPath","lastPoint","getPointSpline","getGraphPath","graphPath","singlePoints","drawGraph","roundCap","linecap","graphKey","clipNeg","translatedThreshold","posAttr","negAttr","above","below","negativeFillColor","posClip","negClip","chartSizeMax","invertGroups","setInvert","groupName","doAnimation","chartSeriesGroup","drawTracker","wasDirtyData","vis","showOrHide","oldVisibility","otherSeries","singlePoint","trackByArea","trackerPath","areaPath","trackerPathLength","stroke-linejoin","LineSeries","AreaSeries","keys","pointMap","areaSegmentPath","segLength","closedStacks","closeSegment","areaKey","fillOpacity","spline","SplineSeries","leftContX","leftContY","rightContX","rightContY","correction","lastX","lastY","nextX","nextY","smoothing","areaspline","areaProto","AreaSplineSeries","column","minPointLength","ColumnSeries","trackerGroups","getColumnMetrics","columnIndex","reversedXAxis","stackGroups","columnCount","grouping","otherOptions","otherYAxis","categoryWidth","pointOffsetWidth","optionPointWidth","pointWidth","columnMetrics","metrics","seriesBarW","xCrisp","yCrisp","fromTop","fromLeft","barX","barY","barH","shapeType","shapeArgs","_hasTracking","dlBox","inside","BarSeries","scatter","ScatterSeries","takeOrdinalPosition","pie","ignoreHiddenPoint","slicedOffset","PieSeries","toggleSlice","sliced","translation","slicedTranslation","shadowGroup","startAngleRad","getCenter","handleSlicingRoom","isPercent","slicingRoom","centerOption","innerSize","smallestSize","radiusX","radiusY","cumulative","connectorOffset","startAngle","circ","endAngleRad","endAngle","labelDistance","getX","asin","half","labelPos","groupTranslation","sortByAngle","connectorPath","dataLabelWidth","labelHeight","rankArr","connectorPadding","connectorWidth","softConnector","distanceOption","seriesCenter","centerY","outside","halves","slotsLength","slotIndex","slots","usedSlots","rank","slotI","closest","slot","naturalY","justify","_attr","_pos","connX","connY","verifyDataLabelOverflow","placeDataLabels","connectorColor","minSize","newSize","moved","getOptions","svg","canvas","vml","product","velirParams","velir","datacenter","UrlParams","getDataResponseOnChange","getDataResponse","getFilterString","filterStringNvc","util","collections","NameValueCollection","indicator","timeFrame","dataFormat","characteristicId","locationId","toQueryString","getDataParams","filterString","Backbone","View","singleBarBaseHeight","multiBarBaseHeight","additionalBarHeight","additionalMultiBarGroup","legendOverhead","legendItemHeight","initialize","bindAll","updateLegendPosition","areModelArraysValid","highCharts","formatYAxisLabels","adjustForSingleCharacteristic","sizeBarChartContainer","orderChartColors","singleCharacteristicConfig","isMultiBarChart","createNestedObject","newValue","$container","$legend","$rect","svgOffset","windowScrollTop","newY","containerOffset","legendTranslation","find","first","scrollTop","calculateCorrectBarHeight","adjustForLegendHeight","calculateMultiBarHeight","calculateSingleBarHeight","locationCount","characteristicCount","arrayLength","arrayDiff","maxLegendSize","legendLines","actualLegendSize","modifiedName","selectorInfo","selectors","characteristics","characteristic","templateSelector","initialRenderPromise","Deferred","getInitialRenderPromise","loadTemplate","template","$tmpl","templateData","shouldDrawHeader","currentIndicatorId","indicatorName","indicators","dataFormatName","dataFormats","fadeIn","resolve","NoDataView","selectorNs","initializeView","instances","updateDataSummary","initializeSelectors","allSelectors","breakdownSelectorView","MultipleBreakdownSelectorView","locationSelectorView","LocationSelectorView","dataTypeSelectorView","DataTypeSelectorView","getSelectorInfoFunc","getSelectorInfoOrThrow","timeFrameSelectorView","TimeFrameSelectorView","getIndicatorSpecificSelectors","getDataSummary","renderSelectors","indicatorSpecificSelectors","indicatorSelectorInfo","shapeLocations","orphanLocations","locationTypes","sortBy","locationType","displayOrder","locations"],"mappings":"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","file":"bar-generated.js","sourcesContent":["/// \r\n/// \r\n\r\n(function() {\r\n \"use strict\";\r\n\r\n var ns;\r\n\r\n ns = window.nspace(\"ccc.viz.bar.config\");\r\n\r\n ns.Config = {\r\n dataUrl: \"/api/BarData/GetBarData\",\r\n /**\r\n * Default highcharts configuration object. Note: changing font sizes, weights, etc. change app calculations,\r\n * so modifier beware.\r\n */\r\n defaultHighchartsConfig: {\r\n chart: {\r\n type: \"bar\",\r\n marginRight: 210\r\n },\r\n colors: [\r\n {\r\n linearGradient: { x1: 0, x2: 1, y0: 0, y1: 0 },\r\n stops: [[0, \"#7ACCD6\"], [1, \"#41b6c4\"]]\r\n },\r\n {\r\n linearGradient: { x1: 0, x2: 1, y0: 0, y1: 0 },\r\n stops: [[0, \"#858EC3\"], [1, \"#515da9\"]]\r\n },\r\n {\r\n linearGradient: { x1: 0, x2: 1, y0: 0, y1: 0 },\r\n stops: [[0, \"#BDE5CA\"], [1, \"#a1dab4\"]]\r\n },\r\n {\r\n linearGradient: { x1: 0, x2: 1, y0: 0, y1: 0 },\r\n stops: [[0, \"#4DACDB\"], [1, \"#0089cc\"]]\r\n },\r\n {\r\n linearGradient: { x1: 0, x2: 1, y0: 0, y1: 0 },\r\n stops: [[0, \"#C2C6E1\"], [1, \"#a8aed4\"]]\r\n },\r\n {\r\n linearGradient: { x1: 0, x2: 1, y0: 0, y1: 0 },\r\n stops: [[0, \"#95D268\"], [1, \"#68be27\"]]\r\n },\r\n {\r\n linearGradient: { x1: 0, x2: 1, y0: 0, y1: 0 },\r\n stops: [[0, \"#B8B8B8\"], [1, \"#999999\"]]\r\n },\r\n {\r\n linearGradient: { x1: 0, x2: 1, y0: 0, y1: 0 },\r\n stops: [[0, \"#C0E1EA\"], [1, \"#a5d4e1\"]]\r\n }\r\n ],\r\n credits: {\r\n enabled: false\r\n },\r\n title: {\r\n text: null\r\n },\r\n yAxis: {\r\n opposite: true,\r\n title: {\r\n text: null\r\n },\r\n gridLineWidth: 0,\r\n labels: {\r\n style: {\r\n \"font-family\":\r\n \"GestaCond-Bold, 'GestaCond-Bold', Tahoma, Arial, sans-serif;\",\r\n \"font-size\": \"15px\",\r\n color: \"#000\"\r\n }\r\n },\r\n lineWidth: 2,\r\n lineColor: \"#EBEBEB\"\r\n },\r\n xAxis: {\r\n gridLineWidth: 2,\r\n gridLineColor: \"#EBEBEB\",\r\n lineWidth: 2,\r\n lineColor: \"#EBEBEB\",\r\n tickLength: 0,\r\n tickInterval: 1,\r\n labels: {\r\n style: {\r\n \"font-family\":\r\n \"GestaCond-Bold, 'GestaCond-Bold', Tahoma, Arial, sans-serif;\",\r\n \"font-size\": \"15px\",\r\n color: \"#000\"\r\n }\r\n }\r\n },\r\n plotOptions: {\r\n bar: {\r\n dataLabels: {\r\n enabled: true,\r\n crop: false,\r\n overflow: \"none\",\r\n format:\r\n \"{point.name}\",\r\n style: {\r\n \"font-size\": \"13px\",\r\n color: \"#000\"\r\n }\r\n },\r\n groupPadding: 0.08,\r\n pointPadding: 0.03,\r\n events: {\r\n legendItemClick: function() {\r\n return false;\r\n }\r\n }\r\n }\r\n },\r\n legend: {\r\n align: \"right\",\r\n borderRadius: 0,\r\n borderColor: \"#bfe5f0\",\r\n borderWidth: 2,\r\n verticalAlign: \"top\",\r\n layout: \"vertical\",\r\n useHTML: false,\r\n width: 150,\r\n backgroundColor: {\r\n linearGradient: { x1: 0, x2: 0, y0: 0, y1: 1 },\r\n stops: [[0, \"#FFF\"], [1, \"#e9f6fa\"]]\r\n },\r\n itemStyle: {\r\n \"font-family\":\r\n \"GestaCond-Bold, 'GestaCond-Bold', Tahoma, Arial, sans-serif;\",\r\n \"font-size\": \"15px\",\r\n color: \"#000\",\r\n cursor: \"default\"\r\n },\r\n labelFormatter: function() {\r\n var tooltip;\r\n\r\n tooltip = ns.Config.defaultHighchartsConfig.legend.labelFormatterHelper(\r\n this.name\r\n );\r\n return tooltip;\r\n },\r\n /**\r\n * This helper exists to help calculate legends by highcharts and by our app.\r\n */\r\n labelFormatterHelper: function(name) {\r\n var words, charsPerLine, str, charCount, i, tooltip;\r\n\r\n words = name.split(/[\\s]+/);\r\n charsPerLine = 16;\r\n str = [];\r\n charCount = words[0] ? words[0].length : 0;\r\n str.push(words[0]);\r\n\r\n for (i = 1; i < words.length; i++) {\r\n charCount = charCount + words[i].length;\r\n\r\n if (charCount >= charsPerLine) {\r\n str.push(\"
\");\r\n charCount = words[i].length;\r\n }\r\n str.push(words[i]);\r\n }\r\n\r\n tooltip = \"\" + str.join(\" \") + \"\";\r\n\r\n return tooltip;\r\n },\r\n reversed: true\r\n },\r\n tooltip: {\r\n headerFormat: \"\",\r\n pointFormat:\r\n \"{series.name}: {point.name}\",\r\n followPointer: true,\r\n borderWidth: 3,\r\n borderColor: \"#000\",\r\n backgroundColor: \"rgba(255,255,255,1)\",\r\n borderRadius: 8\r\n }\r\n }\r\n };\r\n\r\n ns.SingleCharacteristicConfig = {\r\n legend: {\r\n enabled: false\r\n },\r\n xAxis: {\r\n gridLineWidth: 0\r\n },\r\n plotOptions: {\r\n bar: {\r\n groupPadding: 0,\r\n pointPadding: 0.05\r\n }\r\n }\r\n };\r\n})();\r\n","/// \r\n/// \r\n/// \r\n/// \r\n/// \r\n/// \r\n/// \r\n/// \r\n/// \r\n\r\n(function() {\r\n \"use strict\";\r\n var ns, sharedNs;\r\n\r\n ns = window.nspace(\"ccc.viz.bar\");\r\n sharedNs = window.nspace(\"ccc.viz.shared\");\r\n\r\n ns.BarVizRouter = sharedNs.routers.VizRouterBase.extend({\r\n routes: {\r\n \"\": \"initializeViews\",\r\n \":indicatorId\": \"initializeViews\",\r\n \":indicatorId/:characteristicIds\": \"initializeViews\",\r\n \":indicatorId/:characteristicIds/:locationIds\": \"initializeViews\",\r\n \":indicatorId/:characteristicIds/:locationIds/:dataFormatId\":\r\n \"initializeViews\",\r\n \":indicatorId/:characteristicIds/:locationIds/:dataFormatId/:timeFrameId\":\r\n \"initializeViews\"\r\n },\r\n\r\n /**\r\n * This method will only ever be invoked a single time, so use it to initialize\r\n * the model/view classes and trigger the initial rendering\r\n */\r\n initializeViews: function(\r\n indicatorId,\r\n characteristicIds,\r\n locationIds,\r\n dataFormatId,\r\n timeFrameId\r\n ) {\r\n //// MODELS ////\r\n\r\n function getValue(raw) {\r\n if (typeof raw === \"undefined\" || raw === \"a\") {\r\n return undefined;\r\n }\r\n return raw;\r\n }\r\n\r\n // Create the selectors model, which represents anything that is selectable by the user and tracked in the URL\r\n this.selectorsModel = new sharedNs.models.SelectorsModel();\r\n this.selectorsModel.set(\r\n {\r\n indicatorId: getValue(indicatorId),\r\n characteristicIds: this.getArrayFromModelProperty(characteristicIds),\r\n dataFormatId: getValue(dataFormatId),\r\n timeFrameId: getValue(timeFrameId),\r\n locationIds: this.getArrayFromModelProperty(locationIds)\r\n },\r\n {\r\n silent: true\r\n }\r\n );\r\n\r\n // Create the data response model, the model that is responsible for querying the server-side for data,\r\n // storing the response, and triggering updates to other views after the response has been retrieved\r\n this.dataModel = new ns.models.DataResponseModel({\r\n selectorsModel: this.selectorsModel,\r\n dispatcher: this.dispatcher,\r\n dataUrl: window.ccc.viz.bar.config.Config.dataUrl\r\n });\r\n\r\n //// VIEWS ////\r\n\r\n this.views = {\r\n // Loading spinner (no model required)\r\n loadingSpinner: new sharedNs.views.LoadingSpinnerView({\r\n dispatcher: this.dispatcher\r\n }),\r\n\r\n // Source/Definition/Notes\r\n sourceDefinitionNotesView: new sharedNs.views.SourceDefinitionNotesView(\r\n {\r\n selectorsModel: this.selectorsModel,\r\n model: this.dataModel\r\n }\r\n ),\r\n\r\n // Selectors. These must be instantiated late, since these views are used to bootstrap\r\n // the selectors model values, and certain other views need to hear when the selectors model changes.\r\n selectorsView: new ns.views.SelectorsView({\r\n model: this.selectorsModel,\r\n indicatorGroupId: this.indicatorGroupId,\r\n dispatcher: this.dispatcher,\r\n selectorData: {\r\n indicatorGroupId: this.indicatorGroupId,\r\n vizType: \"Bar\"\r\n }\r\n }),\r\n\r\n barView: new ns.views.BarView({\r\n selectorsModel: this.selectorsModel,\r\n model: this.dataModel,\r\n el: \"#bar-chart-container\"\r\n }),\r\n\r\n headerView: new ns.views.HeaderView({\r\n selectorsModel: this.selectorsModel,\r\n model: this.dataModel\r\n }),\r\n\r\n noBarDataView: new ns.views.NoBarDataView({\r\n selectorsModel: this.selectorsModel,\r\n model: this.dataModel\r\n })\r\n };\r\n\r\n this.completeRouterInitialization();\r\n },\r\n\r\n routeUrlParts: function() {\r\n return [\r\n this.selectorsModel.get(\"indicatorId\"),\r\n this.getStringFromArrayProperty(\r\n this.selectorsModel.get(\"characteristicIds\")\r\n ),\r\n this.getStringFromArrayProperty(this.selectorsModel.get(\"locationIds\")),\r\n this.selectorsModel.get(\"dataFormatId\"),\r\n this.selectorsModel.get(\"timeFrameId\")\r\n ];\r\n }\r\n });\r\n})(_);\r\n","// ==ClosureCompiler==\r\n// @compilation_level SIMPLE_OPTIMIZATIONS\r\n\r\n/**\r\n * @license Highcharts JS v3.0.7 (2013-10-24)\r\n *\r\n * (c) 2009-2013 Torstein Hønsi\r\n *\r\n * License: www.highcharts.com/license\r\n */\r\n\r\n// JSLint options:\r\n/*global Highcharts, document, window, navigator, setInterval, clearInterval, clearTimeout, setTimeout, location, jQuery, $, console, each, grep */\r\n\r\n(function() {\r\n // encapsulated variables\r\n var UNDEFINED,\r\n doc = document,\r\n win = window,\r\n math = Math,\r\n mathRound = math.round,\r\n mathFloor = math.floor,\r\n mathCeil = math.ceil,\r\n mathMax = math.max,\r\n mathMin = math.min,\r\n mathAbs = math.abs,\r\n mathCos = math.cos,\r\n mathSin = math.sin,\r\n mathPI = math.PI,\r\n deg2rad = (mathPI * 2) / 360,\r\n // some variables\r\n userAgent = navigator.userAgent,\r\n isOpera = win.opera,\r\n isIE = /msie/i.test(userAgent) && !isOpera,\r\n docMode8 = doc.documentMode === 8,\r\n isWebKit = /AppleWebKit/.test(userAgent),\r\n isFirefox = /Firefox/.test(userAgent),\r\n isTouchDevice = /(Mobile|Android|Windows Phone)/.test(userAgent),\r\n SVG_NS = \"http://www.w3.org/2000/svg\",\r\n hasSVG =\r\n !!doc.createElementNS &&\r\n !!doc.createElementNS(SVG_NS, \"svg\").createSVGRect,\r\n hasBidiBug = isFirefox && parseInt(userAgent.split(\"Firefox/\")[1], 10) < 4, // issue #38\r\n useCanVG = !hasSVG && !isIE && !!doc.createElement(\"canvas\").getContext,\r\n Renderer,\r\n hasTouch = doc.documentElement.ontouchstart !== UNDEFINED,\r\n symbolSizes = {},\r\n idCounter = 0,\r\n garbageBin,\r\n defaultOptions,\r\n dateFormat, // function\r\n globalAnimation,\r\n pathAnim,\r\n timeUnits,\r\n noop = function() {},\r\n charts = [],\r\n PRODUCT = \"Highcharts\",\r\n VERSION = \"3.0.7\",\r\n // some constants for frequently used strings\r\n DIV = \"div\",\r\n ABSOLUTE = \"absolute\",\r\n RELATIVE = \"relative\",\r\n HIDDEN = \"hidden\",\r\n PREFIX = \"highcharts-\",\r\n VISIBLE = \"visible\",\r\n PX = \"px\",\r\n NONE = \"none\",\r\n M = \"M\",\r\n L = \"L\",\r\n /*\r\n * Empirical lowest possible opacities for TRACKER_FILL\r\n * IE6: 0.002\r\n * IE7: 0.002\r\n * IE8: 0.002\r\n * IE9: 0.00000000001 (unlimited)\r\n * IE10: 0.0001 (exporting only)\r\n * FF: 0.00000000001 (unlimited)\r\n * Chrome: 0.000001\r\n * Safari: 0.000001\r\n * Opera: 0.00000000001 (unlimited)\r\n */\r\n TRACKER_FILL = \"rgba(192,192,192,\" + (hasSVG ? 0.0001 : 0.002) + \")\", // invisible but clickable\r\n //TRACKER_FILL = 'rgba(192,192,192,0.5)',\r\n NORMAL_STATE = \"\",\r\n HOVER_STATE = \"hover\",\r\n SELECT_STATE = \"select\",\r\n MILLISECOND = \"millisecond\",\r\n SECOND = \"second\",\r\n MINUTE = \"minute\",\r\n HOUR = \"hour\",\r\n DAY = \"day\",\r\n WEEK = \"week\",\r\n MONTH = \"month\",\r\n YEAR = \"year\",\r\n // constants for attributes\r\n LINEAR_GRADIENT = \"linearGradient\",\r\n STOPS = \"stops\",\r\n STROKE_WIDTH = \"stroke-width\",\r\n // time methods, changed based on whether or not UTC is used\r\n makeTime,\r\n getMinutes,\r\n getHours,\r\n getDay,\r\n getDate,\r\n getMonth,\r\n getFullYear,\r\n setMinutes,\r\n setHours,\r\n setDate,\r\n setMonth,\r\n setFullYear,\r\n // lookup over the types and the associated classes\r\n seriesTypes = {};\r\n\r\n // The Highcharts namespace\r\n win.Highcharts = win.Highcharts ? error(16, true) : {};\r\n\r\n /**\r\n * Extend an object with the members of another\r\n * @param {Object} a The object to be extended\r\n * @param {Object} b The object to add to the first one\r\n */\r\n function extend(a, b) {\r\n var n;\r\n if (!a) {\r\n a = {};\r\n }\r\n for (n in b) {\r\n a[n] = b[n];\r\n }\r\n return a;\r\n }\r\n\r\n /**\r\n * Deep merge two or more objects and return a third object.\r\n * Previously this function redirected to jQuery.extend(true), but this had two limitations.\r\n * First, it deep merged arrays, which lead to workarounds in Highcharts. Second,\r\n * it copied properties from extended prototypes.\r\n */\r\n function merge() {\r\n var i,\r\n len = arguments.length,\r\n ret = {},\r\n doCopy = function(copy, original) {\r\n var value, key;\r\n\r\n // An object is replacing a primitive\r\n if (typeof copy !== \"object\") {\r\n copy = {};\r\n }\r\n\r\n for (key in original) {\r\n if (original.hasOwnProperty(key)) {\r\n value = original[key];\r\n\r\n // Copy the contents of objects, but not arrays or DOM nodes\r\n if (\r\n value &&\r\n typeof value === \"object\" &&\r\n Object.prototype.toString.call(value) !== \"[object Array]\" &&\r\n typeof value.nodeType !== \"number\"\r\n ) {\r\n copy[key] = doCopy(copy[key] || {}, value);\r\n\r\n // Primitives and arrays are copied over directly\r\n }\r\n else {\r\n copy[key] = original[key];\r\n }\r\n }\r\n }\r\n return copy;\r\n };\r\n\r\n // For each argument, extend the return\r\n for (i = 0; i < len; i++) {\r\n ret = doCopy(ret, arguments[i]);\r\n }\r\n\r\n return ret;\r\n }\r\n\r\n /**\r\n * Take an array and turn into a hash with even number arguments as keys and odd numbers as\r\n * values. Allows creating constants for commonly used style properties, attributes etc.\r\n * Avoid it in performance critical situations like looping\r\n */\r\n function hash() {\r\n var i = 0,\r\n args = arguments,\r\n length = args.length,\r\n obj = {};\r\n for (; i < length; i++) {\r\n obj[args[i++]] = args[i];\r\n }\r\n return obj;\r\n }\r\n\r\n /**\r\n * Shortcut for parseInt\r\n * @param {Object} s\r\n * @param {Number} mag Magnitude\r\n */\r\n function pInt(s, mag) {\r\n return parseInt(s, mag || 10);\r\n }\r\n\r\n /**\r\n * Check for string\r\n * @param {Object} s\r\n */\r\n function isString(s) {\r\n return typeof s === \"string\";\r\n }\r\n\r\n /**\r\n * Check for object\r\n * @param {Object} obj\r\n */\r\n function isObject(obj) {\r\n return typeof obj === \"object\";\r\n }\r\n\r\n /**\r\n * Check for array\r\n * @param {Object} obj\r\n */\r\n function isArray(obj) {\r\n return Object.prototype.toString.call(obj) === \"[object Array]\";\r\n }\r\n\r\n /**\r\n * Check for number\r\n * @param {Object} n\r\n */\r\n function isNumber(n) {\r\n return typeof n === \"number\";\r\n }\r\n\r\n function log2lin(num) {\r\n return math.log(num) / math.LN10;\r\n }\r\n function lin2log(num) {\r\n return math.pow(10, num);\r\n }\r\n\r\n /**\r\n * Remove last occurence of an item from an array\r\n * @param {Array} arr\r\n * @param {Mixed} item\r\n */\r\n function erase(arr, item) {\r\n var i = arr.length;\r\n while (i--) {\r\n if (arr[i] === item) {\r\n arr.splice(i, 1);\r\n break;\r\n }\r\n }\r\n //return arr;\r\n }\r\n\r\n /**\r\n * Returns true if the object is not null or undefined. Like MooTools' $.defined.\r\n * @param {Object} obj\r\n */\r\n function defined(obj) {\r\n return obj !== UNDEFINED && obj !== null;\r\n }\r\n\r\n /**\r\n * Set or get an attribute or an object of attributes. Can't use jQuery attr because\r\n * it attempts to set expando properties on the SVG element, which is not allowed.\r\n *\r\n * @param {Object} elem The DOM element to receive the attribute(s)\r\n * @param {String|Object} prop The property or an abject of key-value pairs\r\n * @param {String} value The value if a single property is set\r\n */\r\n function attr(elem, prop, value) {\r\n var key,\r\n setAttribute = \"setAttribute\",\r\n ret;\r\n\r\n // if the prop is a string\r\n if (isString(prop)) {\r\n // set the value\r\n if (defined(value)) {\r\n elem[setAttribute](prop, value);\r\n\r\n // get the value\r\n }\r\n else if (elem && elem.getAttribute) {\r\n // elem not defined when printing pie demo...\r\n ret = elem.getAttribute(prop);\r\n }\r\n\r\n // else if prop is defined, it is a hash of key/value pairs\r\n }\r\n else if (defined(prop) && isObject(prop)) {\r\n for (key in prop) {\r\n elem[setAttribute](key, prop[key]);\r\n }\r\n }\r\n return ret;\r\n }\r\n /**\r\n * Check if an element is an array, and if not, make it into an array. Like\r\n * MooTools' $.splat.\r\n */\r\n function splat(obj) {\r\n return isArray(obj) ? obj : [obj];\r\n }\r\n\r\n /**\r\n * Return the first value that is defined. Like MooTools' $.pick.\r\n */\r\n function pick() {\r\n var args = arguments,\r\n i,\r\n arg,\r\n length = args.length;\r\n for (i = 0; i < length; i++) {\r\n arg = args[i];\r\n if (typeof arg !== \"undefined\" && arg !== null) {\r\n return arg;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Set CSS on a given element\r\n * @param {Object} el\r\n * @param {Object} styles Style object with camel case property names\r\n */\r\n function css(el, styles) {\r\n if (isIE) {\r\n if (styles && styles.opacity !== UNDEFINED) {\r\n styles.filter = \"alpha(opacity=\" + styles.opacity * 100 + \")\";\r\n }\r\n }\r\n extend(el.style, styles);\r\n }\r\n\r\n /**\r\n * Utility function to create element with attributes and styles\r\n * @param {Object} tag\r\n * @param {Object} attribs\r\n * @param {Object} styles\r\n * @param {Object} parent\r\n * @param {Object} nopad\r\n */\r\n function createElement(tag, attribs, styles, parent, nopad) {\r\n var el = doc.createElement(tag);\r\n if (attribs) {\r\n extend(el, attribs);\r\n }\r\n if (nopad) {\r\n css(el, { padding: 0, border: NONE, margin: 0 });\r\n }\r\n if (styles) {\r\n css(el, styles);\r\n }\r\n if (parent) {\r\n parent.appendChild(el);\r\n }\r\n return el;\r\n }\r\n\r\n /**\r\n * Extend a prototyped class by new members\r\n * @param {Object} parent\r\n * @param {Object} members\r\n */\r\n function extendClass(parent, members) {\r\n var object = function() {};\r\n object.prototype = new parent();\r\n extend(object.prototype, members);\r\n return object;\r\n }\r\n\r\n /**\r\n * Format a number and return a string based on input settings\r\n * @param {Number} number The input number to format\r\n * @param {Number} decimals The amount of decimals\r\n * @param {String} decPoint The decimal point, defaults to the one given in the lang options\r\n * @param {String} thousandsSep The thousands separator, defaults to the one given in the lang options\r\n */\r\n function numberFormat(number, decimals, decPoint, thousandsSep) {\r\n var lang = defaultOptions.lang,\r\n // http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_number_format/\r\n n = +number || 0,\r\n c =\r\n decimals === -1\r\n ? (n.toString().split(\".\")[1] || \"\").length // preserve decimals\r\n : isNaN((decimals = mathAbs(decimals)))\r\n ? 2\r\n : decimals,\r\n d = decPoint === undefined ? lang.decimalPoint : decPoint,\r\n t = thousandsSep === undefined ? lang.thousandsSep : thousandsSep,\r\n s = n < 0 ? \"-\" : \"\",\r\n i = String(pInt((n = mathAbs(n).toFixed(c)))),\r\n j = i.length > 3 ? i.length % 3 : 0;\r\n\r\n return (\r\n s +\r\n (j ? i.substr(0, j) + t : \"\") +\r\n i.substr(j).replace(/(\\d{3})(?=\\d)/g, \"$1\" + t) +\r\n (c\r\n ? d +\r\n mathAbs(n - i)\r\n .toFixed(c)\r\n .slice(2)\r\n : \"\")\r\n );\r\n }\r\n\r\n /**\r\n * Pad a string to a given length by adding 0 to the beginning\r\n * @param {Number} number\r\n * @param {Number} length\r\n */\r\n function pad(number, length) {\r\n // Create an array of the remaining length +1 and join it with 0's\r\n return (\r\n new Array((length || 2) + 1 - String(number).length).join(0) + number\r\n );\r\n }\r\n\r\n /**\r\n * Wrap a method with extended functionality, preserving the original function\r\n * @param {Object} obj The context object that the method belongs to\r\n * @param {String} method The name of the method to extend\r\n * @param {Function} func A wrapper function callback. This function is called with the same arguments\r\n * as the original function, except that the original function is unshifted and passed as the first\r\n * argument.\r\n */\r\n function wrap(obj, method, func) {\r\n var proceed = obj[method];\r\n obj[method] = function() {\r\n var args = Array.prototype.slice.call(arguments);\r\n args.unshift(proceed);\r\n return func.apply(this, args);\r\n };\r\n }\r\n\r\n /**\r\n * Based on http://www.php.net/manual/en/function.strftime.php\r\n * @param {String} format\r\n * @param {Number} timestamp\r\n * @param {Boolean} capitalize\r\n */\r\n dateFormat = function(format, timestamp, capitalize) {\r\n if (!defined(timestamp) || isNaN(timestamp)) {\r\n return \"Invalid date\";\r\n }\r\n format = pick(format, \"%Y-%m-%d %H:%M:%S\");\r\n\r\n var date = new Date(timestamp),\r\n key, // used in for constuct below\r\n // get the basic time values\r\n hours = date[getHours](),\r\n day = date[getDay](),\r\n dayOfMonth = date[getDate](),\r\n month = date[getMonth](),\r\n fullYear = date[getFullYear](),\r\n lang = defaultOptions.lang,\r\n langWeekdays = lang.weekdays,\r\n // List all format keys. Custom formats can be added from the outside.\r\n replacements = extend(\r\n {\r\n // Day\r\n a: langWeekdays[day].substr(0, 3), // Short weekday, like 'Mon'\r\n A: langWeekdays[day], // Long weekday, like 'Monday'\r\n d: pad(dayOfMonth), // Two digit day of the month, 01 to 31\r\n e: dayOfMonth, // Day of the month, 1 through 31\r\n\r\n // Week (none implemented)\r\n //'W': weekNumber(),\r\n\r\n // Month\r\n b: lang.shortMonths[month], // Short month, like 'Jan'\r\n B: lang.months[month], // Long month, like 'January'\r\n m: pad(month + 1), // Two digit month number, 01 through 12\r\n\r\n // Year\r\n y: fullYear.toString().substr(2, 2), // Two digits year, like 09 for 2009\r\n Y: fullYear, // Four digits year, like 2009\r\n\r\n // Time\r\n H: pad(hours), // Two digits hours in 24h format, 00 through 23\r\n I: pad(hours % 12 || 12), // Two digits hours in 12h format, 00 through 11\r\n l: hours % 12 || 12, // Hours in 12h format, 1 through 12\r\n M: pad(date[getMinutes]()), // Two digits minutes, 00 through 59\r\n p: hours < 12 ? \"AM\" : \"PM\", // Upper case AM or PM\r\n P: hours < 12 ? \"am\" : \"pm\", // Lower case AM or PM\r\n S: pad(date.getSeconds()), // Two digits seconds, 00 through 59\r\n L: pad(mathRound(timestamp % 1000), 3) // Milliseconds (naming from Ruby)\r\n },\r\n Highcharts.dateFormats\r\n );\r\n\r\n // do the replaces\r\n for (key in replacements) {\r\n while (format.indexOf(\"%\" + key) !== -1) {\r\n // regex would do it in one line, but this is faster\r\n format = format.replace(\r\n \"%\" + key,\r\n typeof replacements[key] === \"function\"\r\n ? replacements[key](timestamp)\r\n : replacements[key]\r\n );\r\n }\r\n }\r\n\r\n // Optionally capitalize the string and return\r\n return capitalize\r\n ? format.substr(0, 1).toUpperCase() + format.substr(1)\r\n : format;\r\n };\r\n\r\n /**\r\n * Format a single variable. Similar to sprintf, without the % prefix.\r\n */\r\n function formatSingle(format, val) {\r\n var floatRegex = /f$/,\r\n decRegex = /\\.([0-9])/,\r\n lang = defaultOptions.lang,\r\n decimals;\r\n\r\n if (floatRegex.test(format)) {\r\n // float\r\n decimals = format.match(decRegex);\r\n decimals = decimals ? decimals[1] : -1;\r\n val = numberFormat(\r\n val,\r\n decimals,\r\n lang.decimalPoint,\r\n format.indexOf(\",\") > -1 ? lang.thousandsSep : \"\"\r\n );\r\n }\r\n else {\r\n val = dateFormat(format, val);\r\n }\r\n return val;\r\n }\r\n\r\n /**\r\n * Format a string according to a subset of the rules of Python's String.format method.\r\n */\r\n function format(str, ctx) {\r\n var splitter = \"{\",\r\n isInside = false,\r\n segment,\r\n valueAndFormat,\r\n path,\r\n i,\r\n len,\r\n ret = [],\r\n val,\r\n index;\r\n\r\n while ((index = str.indexOf(splitter)) !== -1) {\r\n segment = str.slice(0, index);\r\n if (isInside) {\r\n // we're on the closing bracket looking back\r\n\r\n valueAndFormat = segment.split(\":\");\r\n path = valueAndFormat.shift().split(\".\"); // get first and leave format\r\n len = path.length;\r\n val = ctx;\r\n\r\n // Assign deeper paths\r\n for (i = 0; i < len; i++) {\r\n val = val[path[i]];\r\n }\r\n\r\n // Format the replacement\r\n if (valueAndFormat.length) {\r\n val = formatSingle(valueAndFormat.join(\":\"), val);\r\n }\r\n\r\n // Push the result and advance the cursor\r\n ret.push(val);\r\n }\r\n else {\r\n ret.push(segment);\r\n }\r\n str = str.slice(index + 1); // the rest\r\n isInside = !isInside; // toggle\r\n splitter = isInside ? \"}\" : \"{\"; // now look for next matching bracket\r\n }\r\n ret.push(str);\r\n return ret.join(\"\");\r\n }\r\n\r\n /**\r\n * Get the magnitude of a number\r\n */\r\n function getMagnitude(num) {\r\n return math.pow(10, mathFloor(math.log(num) / math.LN10));\r\n }\r\n\r\n /**\r\n * Take an interval and normalize it to multiples of 1, 2, 2.5 and 5\r\n * @param {Number} interval\r\n * @param {Array} multiples\r\n * @param {Number} magnitude\r\n * @param {Object} options\r\n */\r\n function normalizeTickInterval(interval, multiples, magnitude, options) {\r\n var normalized, i;\r\n\r\n // round to a tenfold of 1, 2, 2.5 or 5\r\n magnitude = pick(magnitude, 1);\r\n normalized = interval / magnitude;\r\n\r\n // multiples for a linear scale\r\n if (!multiples) {\r\n multiples = [1, 2, 2.5, 5, 10];\r\n\r\n // the allowDecimals option\r\n if (options && options.allowDecimals === false) {\r\n if (magnitude === 1) {\r\n multiples = [1, 2, 5, 10];\r\n }\r\n else if (magnitude <= 0.1) {\r\n multiples = [1 / magnitude];\r\n }\r\n }\r\n }\r\n\r\n // normalize the interval to the nearest multiple\r\n for (i = 0; i < multiples.length; i++) {\r\n interval = multiples[i];\r\n if (\r\n normalized <=\r\n (multiples[i] + (multiples[i + 1] || multiples[i])) / 2\r\n ) {\r\n break;\r\n }\r\n }\r\n\r\n // multiply back to the correct magnitude\r\n interval *= magnitude;\r\n\r\n return interval;\r\n }\r\n\r\n /**\r\n * Get a normalized tick interval for dates. Returns a configuration object with\r\n * unit range (interval), count and name. Used to prepare data for getTimeTicks.\r\n * Previously this logic was part of getTimeTicks, but as getTimeTicks now runs\r\n * of segments in stock charts, the normalizing logic was extracted in order to\r\n * prevent it for running over again for each segment having the same interval.\r\n * #662, #697.\r\n */\r\n function normalizeTimeTickInterval(tickInterval, unitsOption) {\r\n var units = unitsOption || [\r\n [\r\n MILLISECOND, // unit name\r\n [1, 2, 5, 10, 20, 25, 50, 100, 200, 500] // allowed multiples\r\n ],\r\n [SECOND, [1, 2, 5, 10, 15, 30]],\r\n [MINUTE, [1, 2, 5, 10, 15, 30]],\r\n [HOUR, [1, 2, 3, 4, 6, 8, 12]],\r\n [DAY, [1, 2]],\r\n [WEEK, [1, 2]],\r\n [MONTH, [1, 2, 3, 4, 6]],\r\n [YEAR, null]\r\n ],\r\n unit = units[units.length - 1], // default unit is years\r\n interval = timeUnits[unit[0]],\r\n multiples = unit[1],\r\n count,\r\n i;\r\n\r\n // loop through the units to find the one that best fits the tickInterval\r\n for (i = 0; i < units.length; i++) {\r\n unit = units[i];\r\n interval = timeUnits[unit[0]];\r\n multiples = unit[1];\r\n\r\n if (units[i + 1]) {\r\n // lessThan is in the middle between the highest multiple and the next unit.\r\n var lessThan =\r\n (interval * multiples[multiples.length - 1] +\r\n timeUnits[units[i + 1][0]]) /\r\n 2;\r\n\r\n // break and keep the current unit\r\n if (tickInterval <= lessThan) {\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // prevent 2.5 years intervals, though 25, 250 etc. are allowed\r\n if (interval === timeUnits[YEAR] && tickInterval < 5 * interval) {\r\n multiples = [1, 2, 5];\r\n }\r\n\r\n // get the count\r\n count = normalizeTickInterval(\r\n tickInterval / interval,\r\n multiples,\r\n unit[0] === YEAR ? mathMax(getMagnitude(tickInterval / interval), 1) : 1 // #1913, #2360\r\n );\r\n\r\n return {\r\n unitRange: interval,\r\n count: count,\r\n unitName: unit[0]\r\n };\r\n }\r\n\r\n /**\r\n * Set the tick positions to a time unit that makes sense, for example\r\n * on the first of each month or on every Monday. Return an array\r\n * with the time positions. Used in datetime axes as well as for grouping\r\n * data on a datetime axis.\r\n *\r\n * @param {Object} normalizedInterval The interval in axis values (ms) and the count\r\n * @param {Number} min The minimum in axis values\r\n * @param {Number} max The maximum in axis values\r\n * @param {Number} startOfWeek\r\n */\r\n function getTimeTicks(normalizedInterval, min, max, startOfWeek) {\r\n var tickPositions = [],\r\n i,\r\n higherRanks = {},\r\n useUTC = defaultOptions.global.useUTC,\r\n minYear, // used in months and years as a basis for Date.UTC()\r\n minDate = new Date(min),\r\n interval = normalizedInterval.unitRange,\r\n count = normalizedInterval.count;\r\n\r\n if (defined(min)) {\r\n // #1300\r\n if (interval >= timeUnits[SECOND]) {\r\n // second\r\n minDate.setMilliseconds(0);\r\n minDate.setSeconds(\r\n interval >= timeUnits[MINUTE]\r\n ? 0\r\n : count * mathFloor(minDate.getSeconds() / count)\r\n );\r\n }\r\n\r\n if (interval >= timeUnits[MINUTE]) {\r\n // minute\r\n minDate[setMinutes](\r\n interval >= timeUnits[HOUR]\r\n ? 0\r\n : count * mathFloor(minDate[getMinutes]() / count)\r\n );\r\n }\r\n\r\n if (interval >= timeUnits[HOUR]) {\r\n // hour\r\n minDate[setHours](\r\n interval >= timeUnits[DAY]\r\n ? 0\r\n : count * mathFloor(minDate[getHours]() / count)\r\n );\r\n }\r\n\r\n if (interval >= timeUnits[DAY]) {\r\n // day\r\n minDate[setDate](\r\n interval >= timeUnits[MONTH]\r\n ? 1\r\n : count * mathFloor(minDate[getDate]() / count)\r\n );\r\n }\r\n\r\n if (interval >= timeUnits[MONTH]) {\r\n // month\r\n minDate[setMonth](\r\n interval >= timeUnits[YEAR]\r\n ? 0\r\n : count * mathFloor(minDate[getMonth]() / count)\r\n );\r\n minYear = minDate[getFullYear]();\r\n }\r\n\r\n if (interval >= timeUnits[YEAR]) {\r\n // year\r\n minYear -= minYear % count;\r\n minDate[setFullYear](minYear);\r\n }\r\n\r\n // week is a special case that runs outside the hierarchy\r\n if (interval === timeUnits[WEEK]) {\r\n // get start of current week, independent of count\r\n minDate[setDate](\r\n minDate[getDate]() - minDate[getDay]() + pick(startOfWeek, 1)\r\n );\r\n }\r\n\r\n // get tick positions\r\n i = 1;\r\n minYear = minDate[getFullYear]();\r\n var time = minDate.getTime(),\r\n minMonth = minDate[getMonth](),\r\n minDateDate = minDate[getDate](),\r\n timezoneOffset = useUTC\r\n ? 0\r\n : (24 * 3600 * 1000 + minDate.getTimezoneOffset() * 60 * 1000) %\r\n (24 * 3600 * 1000); // #950\r\n\r\n // iterate and add tick positions at appropriate values\r\n while (time < max) {\r\n tickPositions.push(time);\r\n\r\n // if the interval is years, use Date.UTC to increase years\r\n if (interval === timeUnits[YEAR]) {\r\n time = makeTime(minYear + i * count, 0);\r\n\r\n // if the interval is months, use Date.UTC to increase months\r\n }\r\n else if (interval === timeUnits[MONTH]) {\r\n time = makeTime(minYear, minMonth + i * count);\r\n\r\n // if we're using global time, the interval is not fixed as it jumps\r\n // one hour at the DST crossover\r\n }\r\n else if (\r\n !useUTC &&\r\n (interval === timeUnits[DAY] || interval === timeUnits[WEEK])\r\n ) {\r\n time = makeTime(\r\n minYear,\r\n minMonth,\r\n minDateDate + i * count * (interval === timeUnits[DAY] ? 1 : 7)\r\n );\r\n\r\n // else, the interval is fixed and we use simple addition\r\n }\r\n else {\r\n time += interval * count;\r\n }\r\n\r\n i++;\r\n }\r\n\r\n // push the last time\r\n tickPositions.push(time);\r\n\r\n // mark new days if the time is dividible by day (#1649, #1760)\r\n each(\r\n grep(tickPositions, function(time) {\r\n return (\r\n interval <= timeUnits[HOUR] &&\r\n time % timeUnits[DAY] === timezoneOffset\r\n );\r\n }),\r\n function(time) {\r\n higherRanks[time] = DAY;\r\n }\r\n );\r\n }\r\n\r\n // record information on the chosen unit - for dynamic label formatter\r\n tickPositions.info = extend(normalizedInterval, {\r\n higherRanks: higherRanks,\r\n totalRange: interval * count\r\n });\r\n\r\n return tickPositions;\r\n }\r\n\r\n /**\r\n * Helper class that contains variuos counters that are local to the chart.\r\n */\r\n function ChartCounters() {\r\n this.color = 0;\r\n this.symbol = 0;\r\n }\r\n\r\n ChartCounters.prototype = {\r\n /**\r\n * Wraps the color counter if it reaches the specified length.\r\n */\r\n wrapColor: function(length) {\r\n if (this.color >= length) {\r\n this.color = 0;\r\n }\r\n },\r\n\r\n /**\r\n * Wraps the symbol counter if it reaches the specified length.\r\n */\r\n wrapSymbol: function(length) {\r\n if (this.symbol >= length) {\r\n this.symbol = 0;\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Utility method that sorts an object array and keeping the order of equal items.\r\n * ECMA script standard does not specify the behaviour when items are equal.\r\n */\r\n function stableSort(arr, sortFunction) {\r\n var length = arr.length,\r\n sortValue,\r\n i;\r\n\r\n // Add index to each item\r\n for (i = 0; i < length; i++) {\r\n arr[i].ss_i = i; // stable sort index\r\n }\r\n\r\n arr.sort(function(a, b) {\r\n sortValue = sortFunction(a, b);\r\n return sortValue === 0 ? a.ss_i - b.ss_i : sortValue;\r\n });\r\n\r\n // Remove index from items\r\n for (i = 0; i < length; i++) {\r\n delete arr[i].ss_i; // stable sort index\r\n }\r\n }\r\n\r\n /**\r\n * Non-recursive method to find the lowest member of an array. Math.min raises a maximum\r\n * call stack size exceeded error in Chrome when trying to apply more than 150.000 points. This\r\n * method is slightly slower, but safe.\r\n */\r\n function arrayMin(data) {\r\n var i = data.length,\r\n min = data[0];\r\n\r\n while (i--) {\r\n if (data[i] < min) {\r\n min = data[i];\r\n }\r\n }\r\n return min;\r\n }\r\n\r\n /**\r\n * Non-recursive method to find the lowest member of an array. Math.min raises a maximum\r\n * call stack size exceeded error in Chrome when trying to apply more than 150.000 points. This\r\n * method is slightly slower, but safe.\r\n */\r\n function arrayMax(data) {\r\n var i = data.length,\r\n max = data[0];\r\n\r\n while (i--) {\r\n if (data[i] > max) {\r\n max = data[i];\r\n }\r\n }\r\n return max;\r\n }\r\n\r\n /**\r\n * Utility method that destroys any SVGElement or VMLElement that are properties on the given object.\r\n * It loops all properties and invokes destroy if there is a destroy method. The property is\r\n * then delete'ed.\r\n * @param {Object} The object to destroy properties on\r\n * @param {Object} Exception, do not destroy this property, only delete it.\r\n */\r\n function destroyObjectProperties(obj, except) {\r\n var n;\r\n for (n in obj) {\r\n // If the object is non-null and destroy is defined\r\n if (obj[n] && obj[n] !== except && obj[n].destroy) {\r\n // Invoke the destroy\r\n obj[n].destroy();\r\n }\r\n\r\n // Delete the property from the object.\r\n delete obj[n];\r\n }\r\n }\r\n\r\n /**\r\n * Discard an element by moving it to the bin and delete\r\n * @param {Object} The HTML node to discard\r\n */\r\n function discardElement(element) {\r\n // create a garbage bin element, not part of the DOM\r\n if (!garbageBin) {\r\n garbageBin = createElement(DIV);\r\n }\r\n\r\n // move the node and empty bin\r\n if (element) {\r\n garbageBin.appendChild(element);\r\n }\r\n garbageBin.innerHTML = \"\";\r\n }\r\n\r\n /**\r\n * Provide error messages for debugging, with links to online explanation\r\n */\r\n function error(code, stop) {\r\n var msg =\r\n \"Highcharts error #\" + code + \": www.highcharts.com/errors/\" + code;\r\n if (stop) {\r\n throw msg;\r\n }\r\n else if (win.console) {\r\n console.log(msg);\r\n }\r\n }\r\n\r\n /**\r\n * Fix JS round off float errors\r\n * @param {Number} num\r\n */\r\n function correctFloat(num) {\r\n return parseFloat(num.toPrecision(14));\r\n }\r\n\r\n /**\r\n * Set the global animation to either a given value, or fall back to the\r\n * given chart's animation option\r\n * @param {Object} animation\r\n * @param {Object} chart\r\n */\r\n function setAnimation(animation, chart) {\r\n globalAnimation = pick(animation, chart.animation);\r\n }\r\n\r\n /**\r\n * The time unit lookup\r\n */\r\n /*jslint white: true*/\r\n timeUnits = hash(\r\n MILLISECOND,\r\n 1,\r\n SECOND,\r\n 1000,\r\n MINUTE,\r\n 60000,\r\n HOUR,\r\n 3600000,\r\n DAY,\r\n 24 * 3600000,\r\n WEEK,\r\n 7 * 24 * 3600000,\r\n MONTH,\r\n 31 * 24 * 3600000,\r\n YEAR,\r\n 31556952000\r\n );\r\n /*jslint white: false*/\r\n /**\r\n * Path interpolation algorithm used across adapters\r\n */\r\n pathAnim = {\r\n /**\r\n * Prepare start and end values so that the path can be animated one to one\r\n */\r\n init: function(elem, fromD, toD) {\r\n fromD = fromD || \"\";\r\n var shift = elem.shift,\r\n bezier = fromD.indexOf(\"C\") > -1,\r\n numParams = bezier ? 7 : 3,\r\n endLength,\r\n slice,\r\n i,\r\n start = fromD.split(\" \"),\r\n end = [].concat(toD), // copy\r\n startBaseLine,\r\n endBaseLine,\r\n sixify = function(arr) {\r\n // in splines make move points have six parameters like bezier curves\r\n i = arr.length;\r\n while (i--) {\r\n if (arr[i] === M) {\r\n arr.splice(\r\n i + 1,\r\n 0,\r\n arr[i + 1],\r\n arr[i + 2],\r\n arr[i + 1],\r\n arr[i + 2]\r\n );\r\n }\r\n }\r\n };\r\n\r\n if (bezier) {\r\n sixify(start);\r\n sixify(end);\r\n }\r\n\r\n // pull out the base lines before padding\r\n if (elem.isArea) {\r\n startBaseLine = start.splice(start.length - 6, 6);\r\n endBaseLine = end.splice(end.length - 6, 6);\r\n }\r\n\r\n // if shifting points, prepend a dummy point to the end path\r\n if (shift <= end.length / numParams && start.length === end.length) {\r\n while (shift--) {\r\n end = []\r\n .concat(end)\r\n .splice(0, numParams)\r\n .concat(end);\r\n }\r\n }\r\n elem.shift = 0; // reset for following animations\r\n\r\n // copy and append last point until the length matches the end length\r\n if (start.length) {\r\n endLength = end.length;\r\n while (start.length < endLength) {\r\n //bezier && sixify(start);\r\n slice = [].concat(start).splice(start.length - numParams, numParams);\r\n if (bezier) {\r\n // disable first control point\r\n slice[numParams - 6] = slice[numParams - 2];\r\n slice[numParams - 5] = slice[numParams - 1];\r\n }\r\n start = start.concat(slice);\r\n }\r\n }\r\n\r\n if (startBaseLine) {\r\n // append the base lines for areas\r\n start = start.concat(startBaseLine);\r\n end = end.concat(endBaseLine);\r\n }\r\n return [start, end];\r\n },\r\n\r\n /**\r\n * Interpolate each value of the path and return the array\r\n */\r\n step: function(start, end, pos, complete) {\r\n var ret = [],\r\n i = start.length,\r\n startVal;\r\n\r\n if (pos === 1) {\r\n // land on the final path without adjustment points appended in the ends\r\n ret = complete;\r\n }\r\n else if (i === end.length && pos < 1) {\r\n while (i--) {\r\n startVal = parseFloat(start[i]);\r\n ret[i] = isNaN(startVal) // a letter instruction like M or L\r\n ? start[i]\r\n : pos * parseFloat(end[i] - startVal) + startVal;\r\n }\r\n }\r\n else {\r\n // if animation is finished or length not matching, land on right value\r\n ret = end;\r\n }\r\n return ret;\r\n }\r\n };\r\n\r\n (function($) {\r\n /**\r\n * The default HighchartsAdapter for jQuery\r\n */\r\n win.HighchartsAdapter =\r\n win.HighchartsAdapter ||\r\n ($ && {\r\n /**\r\n * Initialize the adapter by applying some extensions to jQuery\r\n */\r\n init: function(pathAnim) {\r\n // extend the animate function to allow SVG animations\r\n var Fx = $.fx,\r\n Step = Fx.step,\r\n dSetter,\r\n Tween = $.Tween,\r\n propHooks = Tween && Tween.propHooks,\r\n opacityHook =\r\n $.cssHooks.opacity; /* allow unused param x in this function */\r\n\r\n /*jslint unparam: true*/ $.extend($.easing, {\r\n easeOutQuad: function(x, t, b, c, d) {\r\n return -c * (t /= d) * (t - 2) + b;\r\n }\r\n });\r\n /*jslint unparam: false*/\r\n\r\n // extend some methods to check for elem.attr, which means it is a Highcharts SVG object\r\n $.each([\"cur\", \"_default\", \"width\", \"height\", \"opacity\"], function(\r\n i,\r\n fn\r\n ) {\r\n var obj = Step,\r\n base,\r\n elem;\r\n\r\n // Handle different parent objects\r\n if (fn === \"cur\") {\r\n obj = Fx.prototype; // 'cur', the getter, relates to Fx.prototype\r\n }\r\n else if (fn === \"_default\" && Tween) {\r\n // jQuery 1.8 model\r\n obj = propHooks[fn];\r\n fn = \"set\";\r\n }\r\n\r\n // Overwrite the method\r\n base = obj[fn];\r\n if (base) {\r\n // step.width and step.height don't exist in jQuery < 1.7\r\n\r\n // create the extended function replacement\r\n obj[fn] = function(fx) {\r\n // Fx.prototype.cur does not use fx argument\r\n fx = i ? fx : this;\r\n\r\n // Don't run animations on textual properties like align (#1821)\r\n if (fx.prop === \"align\") {\r\n return;\r\n }\r\n\r\n // shortcut\r\n elem = fx.elem;\r\n\r\n // Fx.prototype.cur returns the current value. The other ones are setters\r\n // and returning a value has no effect.\r\n return elem.attr // is SVG element wrapper\r\n ? elem.attr(fx.prop, fn === \"cur\" ? UNDEFINED : fx.now) // apply the SVG wrapper's method\r\n : base.apply(this, arguments); // use jQuery's built-in method\r\n };\r\n }\r\n });\r\n\r\n // Extend the opacity getter, needed for fading opacity with IE9 and jQuery 1.10+\r\n wrap(opacityHook, \"get\", function(proceed, elem, computed) {\r\n return elem.attr\r\n ? elem.opacity || 0\r\n : proceed.call(this, elem, computed);\r\n });\r\n\r\n // Define the setter function for d (path definitions)\r\n dSetter = function(fx) {\r\n var elem = fx.elem,\r\n ends;\r\n\r\n // Normally start and end should be set in state == 0, but sometimes,\r\n // for reasons unknown, this doesn't happen. Perhaps state == 0 is skipped\r\n // in these cases\r\n if (!fx.started) {\r\n ends = pathAnim.init(elem, elem.d, elem.toD);\r\n fx.start = ends[0];\r\n fx.end = ends[1];\r\n fx.started = true;\r\n }\r\n\r\n // interpolate each value of the path\r\n elem.attr(\"d\", pathAnim.step(fx.start, fx.end, fx.pos, elem.toD));\r\n };\r\n\r\n // jQuery 1.8 style\r\n if (Tween) {\r\n propHooks.d = {\r\n set: dSetter\r\n };\r\n // pre 1.8\r\n }\r\n else {\r\n // animate paths\r\n Step.d = dSetter;\r\n }\r\n\r\n /**\r\n * Utility for iterating over an array. Parameters are reversed compared to jQuery.\r\n * @param {Array} arr\r\n * @param {Function} fn\r\n */\r\n this.each = Array.prototype.forEach\r\n ? function(arr, fn) {\r\n // modern browsers\r\n return Array.prototype.forEach.call(arr, fn);\r\n }\r\n : function(arr, fn) {\r\n // legacy\r\n var i = 0,\r\n len = arr.length;\r\n for (; i < len; i++) {\r\n if (fn.call(arr[i], arr[i], i, arr) === false) {\r\n return i;\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Register Highcharts as a plugin in the respective framework\r\n */\r\n $.fn.highcharts = function() {\r\n var constr = \"Chart\", // default constructor\r\n args = arguments,\r\n options,\r\n ret,\r\n chart;\r\n\r\n if (isString(args[0])) {\r\n constr = args[0];\r\n args = Array.prototype.slice.call(args, 1);\r\n }\r\n options = args[0];\r\n\r\n // Create the chart\r\n if (options !== UNDEFINED) {\r\n /*jslint unused:false*/\r\n options.chart = options.chart || {};\r\n options.chart.renderTo = this[0];\r\n chart = new Highcharts[constr](options, args[1]);\r\n ret = this;\r\n /*jslint unused:true*/\r\n }\r\n\r\n // When called without parameters or with the return argument, get a predefined chart\r\n if (options === UNDEFINED) {\r\n ret = charts[attr(this[0], \"data-highcharts-chart\")];\r\n }\r\n\r\n return ret;\r\n };\r\n },\r\n\r\n /**\r\n * Downloads a script and executes a callback when done.\r\n * @param {String} scriptLocation\r\n * @param {Function} callback\r\n */\r\n getScript: $.getScript,\r\n\r\n /**\r\n * Return the index of an item in an array, or -1 if not found\r\n */\r\n inArray: $.inArray,\r\n\r\n /**\r\n * A direct link to jQuery methods. MooTools and Prototype adapters must be implemented for each case of method.\r\n * @param {Object} elem The HTML element\r\n * @param {String} method Which method to run on the wrapped element\r\n */\r\n adapterRun: function(elem, method) {\r\n return $(elem)[method]();\r\n },\r\n\r\n /**\r\n * Filter an array\r\n */\r\n grep: $.grep,\r\n\r\n /**\r\n * Map an array\r\n * @param {Array} arr\r\n * @param {Function} fn\r\n */\r\n map: function(arr, fn) {\r\n //return jQuery.map(arr, fn);\r\n var results = [],\r\n i = 0,\r\n len = arr.length;\r\n for (; i < len; i++) {\r\n results[i] = fn.call(arr[i], arr[i], i, arr);\r\n }\r\n return results;\r\n },\r\n\r\n /**\r\n * Get the position of an element relative to the top left of the page\r\n */\r\n offset: function(el) {\r\n return $(el).offset();\r\n },\r\n\r\n /**\r\n * Add an event listener\r\n * @param {Object} el A HTML element or custom object\r\n * @param {String} event The event type\r\n * @param {Function} fn The event handler\r\n */\r\n addEvent: function(el, event, fn) {\r\n $(el).bind(event, fn);\r\n },\r\n\r\n /**\r\n * Remove event added with addEvent\r\n * @param {Object} el The object\r\n * @param {String} eventType The event type. Leave blank to remove all events.\r\n * @param {Function} handler The function to remove\r\n */\r\n removeEvent: function(el, eventType, handler) {\r\n // workaround for jQuery issue with unbinding custom events:\r\n // http://forum.jQuery.com/topic/javascript-error-when-unbinding-a-custom-event-using-jQuery-1-4-2\r\n var func = doc.removeEventListener\r\n ? \"removeEventListener\"\r\n : \"detachEvent\";\r\n if (doc[func] && el && !el[func]) {\r\n el[func] = function() {};\r\n }\r\n\r\n $(el).unbind(eventType, handler);\r\n },\r\n\r\n /**\r\n * Fire an event on a custom object\r\n * @param {Object} el\r\n * @param {String} type\r\n * @param {Object} eventArguments\r\n * @param {Function} defaultFunction\r\n */\r\n fireEvent: function(el, type, eventArguments, defaultFunction) {\r\n var event = $.Event(type),\r\n detachedType = \"detached\" + type,\r\n defaultPrevented;\r\n\r\n // Remove warnings in Chrome when accessing layerX and layerY. Although Highcharts\r\n // never uses these properties, Chrome includes them in the default click event and\r\n // raises the warning when they are copied over in the extend statement below.\r\n //\r\n // To avoid problems in IE (see #1010) where we cannot delete the properties and avoid\r\n // testing if they are there (warning in chrome) the only option is to test if running IE.\r\n if (!isIE && eventArguments) {\r\n delete eventArguments.layerX;\r\n delete eventArguments.layerY;\r\n }\r\n\r\n extend(event, eventArguments);\r\n\r\n // Prevent jQuery from triggering the object method that is named the\r\n // same as the event. For example, if the event is 'select', jQuery\r\n // attempts calling el.select and it goes into a loop.\r\n if (el[type]) {\r\n el[detachedType] = el[type];\r\n el[type] = null;\r\n }\r\n\r\n // Wrap preventDefault and stopPropagation in try/catch blocks in\r\n // order to prevent JS errors when cancelling events on non-DOM\r\n // objects. #615.\r\n /*jslint unparam: true*/\r\n $.each([\"preventDefault\", \"stopPropagation\"], function(i, fn) {\r\n var base = event[fn];\r\n event[fn] = function() {\r\n try {\r\n base.call(event);\r\n }\r\n catch (e) {\r\n if (fn === \"preventDefault\") {\r\n defaultPrevented = true;\r\n }\r\n }\r\n };\r\n });\r\n /*jslint unparam: false*/\r\n\r\n // trigger it\r\n $(el).trigger(event);\r\n\r\n // attach the method\r\n if (el[detachedType]) {\r\n el[type] = el[detachedType];\r\n el[detachedType] = null;\r\n }\r\n\r\n if (\r\n defaultFunction &&\r\n !event.isDefaultPrevented() &&\r\n !defaultPrevented\r\n ) {\r\n defaultFunction(event);\r\n }\r\n },\r\n\r\n /**\r\n * Extension method needed for MooTools\r\n */\r\n washMouseEvent: function(e) {\r\n var ret = e.originalEvent || e;\r\n\r\n // computed by jQuery, needed by IE8\r\n if (ret.pageX === UNDEFINED) {\r\n // #1236\r\n ret.pageX = e.pageX;\r\n ret.pageY = e.pageY;\r\n }\r\n\r\n return ret;\r\n },\r\n\r\n /**\r\n * Animate a HTML element or SVG element wrapper\r\n * @param {Object} el\r\n * @param {Object} params\r\n * @param {Object} options jQuery-like animation options: duration, easing, callback\r\n */\r\n animate: function(el, params, options) {\r\n var $el = $(el);\r\n if (!el.style) {\r\n el.style = {}; // #1881\r\n }\r\n if (params.d) {\r\n el.toD = params.d; // keep the array form for paths, used in $.fx.step.d\r\n params.d = 1; // because in jQuery, animating to an array has a different meaning\r\n }\r\n\r\n $el.stop();\r\n if (params.opacity !== UNDEFINED && el.attr) {\r\n params.opacity += \"px\"; // force jQuery to use same logic as width and height (#2161)\r\n }\r\n $el.animate(params, options);\r\n },\r\n /**\r\n * Stop running animation\r\n */\r\n stop: function(el) {\r\n $(el).stop();\r\n }\r\n });\r\n })(win.jQuery);\r\n\r\n // check for a custom HighchartsAdapter defined prior to this file\r\n var globalAdapter = win.HighchartsAdapter,\r\n adapter = globalAdapter || {};\r\n\r\n // Initialize the adapter\r\n if (globalAdapter) {\r\n globalAdapter.init.call(globalAdapter, pathAnim);\r\n }\r\n\r\n // Utility functions. If the HighchartsAdapter is not defined, adapter is an empty object\r\n // and all the utility functions will be null. In that case they are populated by the\r\n // default adapters below.\r\n var adapterRun = adapter.adapterRun,\r\n getScript = adapter.getScript,\r\n inArray = adapter.inArray,\r\n each = adapter.each,\r\n grep = adapter.grep,\r\n offset = adapter.offset,\r\n map = adapter.map,\r\n addEvent = adapter.addEvent,\r\n removeEvent = adapter.removeEvent,\r\n fireEvent = adapter.fireEvent,\r\n washMouseEvent = adapter.washMouseEvent,\r\n animate = adapter.animate,\r\n stop = adapter.stop;\r\n\r\n /* ****************************************************************************\r\n * Handle the options *\r\n *****************************************************************************/\r\n var defaultLabelOptions = {\r\n enabled: true,\r\n // rotation: 0,\r\n // align: 'center',\r\n x: 0,\r\n y: 15,\r\n /*formatter: function () {\r\n\t\treturn this.value;\r\n\t},*/\r\n style: {\r\n color: \"#666\",\r\n cursor: \"default\",\r\n fontSize: \"11px\",\r\n lineHeight: \"14px\"\r\n }\r\n };\r\n\r\n defaultOptions = {\r\n colors: [\r\n \"#2f7ed8\",\r\n \"#0d233a\",\r\n \"#8bbc21\",\r\n \"#910000\",\r\n \"#1aadce\",\r\n \"#492970\",\r\n \"#f28f43\",\r\n \"#77a1e5\",\r\n \"#c42525\",\r\n \"#a6c96a\"\r\n ],\r\n symbols: [\"circle\", \"diamond\", \"square\", \"triangle\", \"triangle-down\"],\r\n lang: {\r\n loading: \"Loading...\",\r\n months: [\r\n \"January\",\r\n \"February\",\r\n \"March\",\r\n \"April\",\r\n \"May\",\r\n \"June\",\r\n \"July\",\r\n \"August\",\r\n \"September\",\r\n \"October\",\r\n \"November\",\r\n \"December\"\r\n ],\r\n shortMonths: [\r\n \"Jan\",\r\n \"Feb\",\r\n \"Mar\",\r\n \"Apr\",\r\n \"May\",\r\n \"Jun\",\r\n \"Jul\",\r\n \"Aug\",\r\n \"Sep\",\r\n \"Oct\",\r\n \"Nov\",\r\n \"Dec\"\r\n ],\r\n weekdays: [\r\n \"Sunday\",\r\n \"Monday\",\r\n \"Tuesday\",\r\n \"Wednesday\",\r\n \"Thursday\",\r\n \"Friday\",\r\n \"Saturday\"\r\n ],\r\n decimalPoint: \".\",\r\n numericSymbols: [\"k\", \"M\", \"G\", \"T\", \"P\", \"E\"], // SI prefixes used in axis labels\r\n resetZoom: \"Reset zoom\",\r\n resetZoomTitle: \"Reset zoom level 1:1\",\r\n thousandsSep: \",\"\r\n },\r\n global: {\r\n useUTC: true,\r\n canvasToolsURL:\r\n \"http://code.highcharts.com/3.0.7/modules/canvas-tools.js\",\r\n VMLRadialGradientURL:\r\n \"http://code.highcharts.com/3.0.7/gfx/vml-radial-gradient.png\"\r\n },\r\n chart: {\r\n //animation: true,\r\n //alignTicks: false,\r\n //reflow: true,\r\n //className: null,\r\n //events: { load, selection },\r\n //margin: [null],\r\n //marginTop: null,\r\n //marginRight: null,\r\n //marginBottom: null,\r\n //marginLeft: null,\r\n borderColor: \"#4572A7\",\r\n //borderWidth: 0,\r\n borderRadius: 5,\r\n defaultSeriesType: \"line\",\r\n ignoreHiddenSeries: true,\r\n //inverted: false,\r\n //shadow: false,\r\n spacing: [10, 10, 15, 10],\r\n //spacingTop: 10,\r\n //spacingRight: 10,\r\n //spacingBottom: 15,\r\n //spacingLeft: 10,\r\n style: {\r\n fontFamily:\r\n '\"Lucida Grande\", \"Lucida Sans Unicode\", Verdana, Arial, Helvetica, sans-serif', // default font\r\n fontSize: \"12px\"\r\n },\r\n backgroundColor: \"#FFFFFF\",\r\n //plotBackgroundColor: null,\r\n plotBorderColor: \"#C0C0C0\",\r\n //plotBorderWidth: 0,\r\n //plotShadow: false,\r\n //zoomType: ''\r\n resetZoomButton: {\r\n theme: {\r\n zIndex: 20\r\n },\r\n position: {\r\n align: \"right\",\r\n x: -10,\r\n //verticalAlign: 'top',\r\n y: 10\r\n }\r\n // relativeTo: 'plot'\r\n }\r\n },\r\n title: {\r\n text: \"Chart title\",\r\n align: \"center\",\r\n // floating: false,\r\n margin: 15,\r\n // x: 0,\r\n // verticalAlign: 'top',\r\n // y: null,\r\n style: {\r\n color: \"#274b6d\", //#3E576F',\r\n fontSize: \"16px\"\r\n }\r\n },\r\n subtitle: {\r\n text: \"\",\r\n align: \"center\",\r\n // floating: false\r\n // x: 0,\r\n // verticalAlign: 'top',\r\n // y: null,\r\n style: {\r\n color: \"#4d759e\"\r\n }\r\n },\r\n\r\n plotOptions: {\r\n line: {\r\n // base series options\r\n allowPointSelect: false,\r\n showCheckbox: false,\r\n animation: {\r\n duration: 1000\r\n },\r\n //connectNulls: false,\r\n //cursor: 'default',\r\n //clip: true,\r\n //dashStyle: null,\r\n //enableMouseTracking: true,\r\n events: {},\r\n //legendIndex: 0,\r\n //linecap: 'round',\r\n lineWidth: 2,\r\n //shadow: false,\r\n // stacking: null,\r\n marker: {\r\n enabled: true,\r\n //symbol: null,\r\n lineWidth: 0,\r\n radius: 4,\r\n lineColor: \"#FFFFFF\",\r\n //fillColor: null,\r\n states: {\r\n // states for a single point\r\n hover: {\r\n enabled: true\r\n //radius: base + 2\r\n },\r\n select: {\r\n fillColor: \"#FFFFFF\",\r\n lineColor: \"#000000\",\r\n lineWidth: 2\r\n }\r\n }\r\n },\r\n point: {\r\n events: {}\r\n },\r\n dataLabels: merge(defaultLabelOptions, {\r\n align: \"center\",\r\n enabled: false,\r\n formatter: function() {\r\n return this.y === null ? \"\" : numberFormat(this.y, -1);\r\n },\r\n verticalAlign: \"bottom\", // above singular point\r\n y: 0\r\n // backgroundColor: undefined,\r\n // borderColor: undefined,\r\n // borderRadius: undefined,\r\n // borderWidth: undefined,\r\n // padding: 3,\r\n // shadow: false\r\n }),\r\n cropThreshold: 300, // draw points outside the plot area when the number of points is less than this\r\n pointRange: 0,\r\n //pointStart: 0,\r\n //pointInterval: 1,\r\n //showInLegend: null, // auto: true for standalone series, false for linked series\r\n states: {\r\n // states for the entire series\r\n hover: {\r\n //enabled: false,\r\n //lineWidth: base + 1,\r\n marker: {\r\n // lineWidth: base + 1,\r\n // radius: base + 1\r\n }\r\n },\r\n select: {\r\n marker: {}\r\n }\r\n },\r\n stickyTracking: true\r\n //tooltip: {\r\n //pointFormat: '{series.name}: {point.y}'\r\n //valueDecimals: null,\r\n //xDateFormat: '%A, %b %e, %Y',\r\n //valuePrefix: '',\r\n //ySuffix: ''\r\n //}\r\n // turboThreshold: 1000\r\n // zIndex: null\r\n }\r\n },\r\n labels: {\r\n //items: [],\r\n style: {\r\n //font: defaultFont,\r\n position: ABSOLUTE,\r\n color: \"#3E576F\"\r\n }\r\n },\r\n legend: {\r\n enabled: true,\r\n align: \"center\",\r\n //floating: false,\r\n layout: \"horizontal\",\r\n labelFormatter: function() {\r\n return this.name;\r\n },\r\n borderWidth: 1,\r\n borderColor: \"#909090\",\r\n borderRadius: 5,\r\n navigation: {\r\n // animation: true,\r\n activeColor: \"#274b6d\",\r\n // arrowSize: 12\r\n inactiveColor: \"#CCC\"\r\n // style: {} // text styles\r\n },\r\n // margin: 10,\r\n // reversed: false,\r\n shadow: false,\r\n // backgroundColor: null,\r\n /*style: {\r\n\t\t\tpadding: '5px'\r\n\t\t},*/\r\n itemStyle: {\r\n cursor: \"pointer\",\r\n color: \"#274b6d\",\r\n fontSize: \"12px\"\r\n },\r\n itemHoverStyle: {\r\n //cursor: 'pointer', removed as of #601\r\n color: \"#000\"\r\n },\r\n itemHiddenStyle: {\r\n color: \"#CCC\"\r\n },\r\n itemCheckboxStyle: {\r\n position: ABSOLUTE,\r\n width: \"13px\", // for IE precision\r\n height: \"13px\"\r\n },\r\n // itemWidth: undefined,\r\n symbolWidth: 16,\r\n symbolPadding: 5,\r\n verticalAlign: \"bottom\",\r\n // width: undefined,\r\n x: 0,\r\n y: 0,\r\n title: {\r\n //text: null,\r\n style: {\r\n fontWeight: \"bold\"\r\n }\r\n }\r\n },\r\n\r\n loading: {\r\n // hideDuration: 100,\r\n labelStyle: {\r\n fontWeight: \"bold\",\r\n position: RELATIVE,\r\n top: \"1em\"\r\n },\r\n // showDuration: 0,\r\n style: {\r\n position: ABSOLUTE,\r\n backgroundColor: \"white\",\r\n opacity: 0.5,\r\n textAlign: \"center\"\r\n }\r\n },\r\n\r\n tooltip: {\r\n enabled: true,\r\n animation: hasSVG,\r\n //crosshairs: null,\r\n backgroundColor: \"rgba(255, 255, 255, .85)\",\r\n borderWidth: 1,\r\n borderRadius: 3,\r\n dateTimeLabelFormats: {\r\n millisecond: \"%A, %b %e, %H:%M:%S.%L\",\r\n second: \"%A, %b %e, %H:%M:%S\",\r\n minute: \"%A, %b %e, %H:%M\",\r\n hour: \"%A, %b %e, %H:%M\",\r\n day: \"%A, %b %e, %Y\",\r\n week: \"Week from %A, %b %e, %Y\",\r\n month: \"%B %Y\",\r\n year: \"%Y\"\r\n },\r\n //formatter: defaultFormatter,\r\n headerFormat: '{point.key}
',\r\n pointFormat:\r\n '{series.name}: {point.y}
',\r\n shadow: true,\r\n //shared: false,\r\n snap: isTouchDevice ? 25 : 10,\r\n style: {\r\n color: \"#333333\",\r\n cursor: \"default\",\r\n fontSize: \"12px\",\r\n padding: \"8px\",\r\n whiteSpace: \"nowrap\"\r\n }\r\n //xDateFormat: '%A, %b %e, %Y',\r\n //valueDecimals: null,\r\n //valuePrefix: '',\r\n //valueSuffix: ''\r\n },\r\n\r\n credits: {\r\n enabled: true,\r\n text: \"Highcharts.com\",\r\n href: \"http://www.highcharts.com\",\r\n position: {\r\n align: \"right\",\r\n x: -10,\r\n verticalAlign: \"bottom\",\r\n y: -5\r\n },\r\n style: {\r\n cursor: \"pointer\",\r\n color: \"#909090\",\r\n fontSize: \"9px\"\r\n }\r\n }\r\n };\r\n\r\n // Series defaults\r\n var defaultPlotOptions = defaultOptions.plotOptions,\r\n defaultSeriesOptions = defaultPlotOptions.line;\r\n\r\n // set the default time methods\r\n setTimeMethods();\r\n\r\n /**\r\n * Set the time methods globally based on the useUTC option. Time method can be either\r\n * local time or UTC (default).\r\n */\r\n function setTimeMethods() {\r\n var useUTC = defaultOptions.global.useUTC,\r\n GET = useUTC ? \"getUTC\" : \"get\",\r\n SET = useUTC ? \"setUTC\" : \"set\";\r\n\r\n makeTime = useUTC\r\n ? Date.UTC\r\n : function(year, month, date, hours, minutes, seconds) {\r\n return new Date(\r\n year,\r\n month,\r\n pick(date, 1),\r\n pick(hours, 0),\r\n pick(minutes, 0),\r\n pick(seconds, 0)\r\n ).getTime();\r\n };\r\n getMinutes = GET + \"Minutes\";\r\n getHours = GET + \"Hours\";\r\n getDay = GET + \"Day\";\r\n getDate = GET + \"Date\";\r\n getMonth = GET + \"Month\";\r\n getFullYear = GET + \"FullYear\";\r\n setMinutes = SET + \"Minutes\";\r\n setHours = SET + \"Hours\";\r\n setDate = SET + \"Date\";\r\n setMonth = SET + \"Month\";\r\n setFullYear = SET + \"FullYear\";\r\n }\r\n\r\n /**\r\n * Merge the default options with custom options and return the new options structure\r\n * @param {Object} options The new custom options\r\n */\r\n function setOptions(options) {\r\n // Pull out axis options and apply them to the respective default axis options\r\n /*defaultXAxisOptions = merge(defaultXAxisOptions, options.xAxis);\r\n\tdefaultYAxisOptions = merge(defaultYAxisOptions, options.yAxis);\r\n\toptions.xAxis = options.yAxis = UNDEFINED;*/\r\n\r\n // Merge in the default options\r\n defaultOptions = merge(defaultOptions, options);\r\n\r\n // Apply UTC\r\n setTimeMethods();\r\n\r\n return defaultOptions;\r\n }\r\n\r\n /**\r\n * Get the updated default options. Merely exposing defaultOptions for outside modules\r\n * isn't enough because the setOptions method creates a new object.\r\n */\r\n function getOptions() {\r\n return defaultOptions;\r\n }\r\n\r\n /**\r\n * Handle color operations. The object methods are chainable.\r\n * @param {String} input The input color in either rbga or hex format\r\n */\r\n var rgbaRegEx = /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*\\)/,\r\n hexRegEx = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,\r\n rgbRegEx = /rgb\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*\\)/;\r\n\r\n var Color = function(input) {\r\n // declare variables\r\n var rgba = [],\r\n result,\r\n stops;\r\n\r\n /**\r\n * Parse the input color to rgba array\r\n * @param {String} input\r\n */\r\n function init(input) {\r\n // Gradients\r\n if (input && input.stops) {\r\n stops = map(input.stops, function(stop) {\r\n return Color(stop[1]);\r\n });\r\n\r\n // Solid colors\r\n }\r\n else {\r\n // rgba\r\n result = rgbaRegEx.exec(input);\r\n if (result) {\r\n rgba = [\r\n pInt(result[1]),\r\n pInt(result[2]),\r\n pInt(result[3]),\r\n parseFloat(result[4], 10)\r\n ];\r\n }\r\n else {\r\n // hex\r\n result = hexRegEx.exec(input);\r\n if (result) {\r\n rgba = [\r\n pInt(result[1], 16),\r\n pInt(result[2], 16),\r\n pInt(result[3], 16),\r\n 1\r\n ];\r\n }\r\n else {\r\n // rgb\r\n result = rgbRegEx.exec(input);\r\n if (result) {\r\n rgba = [pInt(result[1]), pInt(result[2]), pInt(result[3]), 1];\r\n }\r\n }\r\n }\r\n }\r\n }\r\n /**\r\n * Return the color a specified format\r\n * @param {String} format\r\n */\r\n function get(format) {\r\n var ret;\r\n\r\n if (stops) {\r\n ret = merge(input);\r\n ret.stops = [].concat(ret.stops);\r\n each(stops, function(stop, i) {\r\n ret.stops[i] = [ret.stops[i][0], stop.get(format)];\r\n });\r\n\r\n // it's NaN if gradient colors on a column chart\r\n }\r\n else if (rgba && !isNaN(rgba[0])) {\r\n if (format === \"rgb\") {\r\n ret = \"rgb(\" + rgba[0] + \",\" + rgba[1] + \",\" + rgba[2] + \")\";\r\n }\r\n else if (format === \"a\") {\r\n ret = rgba[3];\r\n }\r\n else {\r\n ret = \"rgba(\" + rgba.join(\",\") + \")\";\r\n }\r\n }\r\n else {\r\n ret = input;\r\n }\r\n return ret;\r\n }\r\n\r\n /**\r\n * Brighten the color\r\n * @param {Number} alpha\r\n */\r\n function brighten(alpha) {\r\n if (stops) {\r\n each(stops, function(stop) {\r\n stop.brighten(alpha);\r\n });\r\n }\r\n else if (isNumber(alpha) && alpha !== 0) {\r\n var i;\r\n for (i = 0; i < 3; i++) {\r\n rgba[i] += pInt(alpha * 255);\r\n\r\n if (rgba[i] < 0) {\r\n rgba[i] = 0;\r\n }\r\n if (rgba[i] > 255) {\r\n rgba[i] = 255;\r\n }\r\n }\r\n }\r\n return this;\r\n }\r\n /**\r\n * Set the color's opacity to a given alpha value\r\n * @param {Number} alpha\r\n */\r\n function setOpacity(alpha) {\r\n rgba[3] = alpha;\r\n return this;\r\n }\r\n\r\n // initialize: parse the input\r\n init(input);\r\n\r\n // public methods\r\n return {\r\n get: get,\r\n brighten: brighten,\r\n rgba: rgba,\r\n setOpacity: setOpacity\r\n };\r\n };\r\n\r\n /**\r\n * A wrapper object for SVG elements\r\n */\r\n function SVGElement() {}\r\n\r\n SVGElement.prototype = {\r\n /**\r\n * Initialize the SVG renderer\r\n * @param {Object} renderer\r\n * @param {String} nodeName\r\n */\r\n init: function(renderer, nodeName) {\r\n var wrapper = this;\r\n wrapper.element =\r\n nodeName === \"span\"\r\n ? createElement(nodeName)\r\n : doc.createElementNS(SVG_NS, nodeName);\r\n wrapper.renderer = renderer;\r\n /**\r\n * A collection of attribute setters. These methods, if defined, are called right before a certain\r\n * attribute is set on an element wrapper. Returning false prevents the default attribute\r\n * setter to run. Returning a value causes the default setter to set that value. Used in\r\n * Renderer.label.\r\n */\r\n wrapper.attrSetters = {};\r\n },\r\n /**\r\n * Default base for animation\r\n */\r\n opacity: 1,\r\n /**\r\n * Animate a given attribute\r\n * @param {Object} params\r\n * @param {Number} options The same options as in jQuery animation\r\n * @param {Function} complete Function to perform at the end of animation\r\n */\r\n animate: function(params, options, complete) {\r\n var animOptions = pick(options, globalAnimation, true);\r\n stop(this); // stop regardless of animation actually running, or reverting to .attr (#607)\r\n if (animOptions) {\r\n animOptions = merge(animOptions);\r\n if (complete) {\r\n // allows using a callback with the global animation without overwriting it\r\n animOptions.complete = complete;\r\n }\r\n animate(this, params, animOptions);\r\n }\r\n else {\r\n this.attr(params);\r\n if (complete) {\r\n complete();\r\n }\r\n }\r\n },\r\n /**\r\n * Set or get a given attribute\r\n * @param {Object|String} hash\r\n * @param {Mixed|Undefined} val\r\n */\r\n attr: function(hash, val) {\r\n var wrapper = this,\r\n key,\r\n value,\r\n result,\r\n i,\r\n child,\r\n element = wrapper.element,\r\n nodeName = element.nodeName.toLowerCase(), // Android2 requires lower for \"text\"\r\n renderer = wrapper.renderer,\r\n skipAttr,\r\n titleNode,\r\n attrSetters = wrapper.attrSetters,\r\n shadows = wrapper.shadows,\r\n hasSetSymbolSize,\r\n doTransform,\r\n ret = wrapper;\r\n\r\n // single key-value pair\r\n if (isString(hash) && defined(val)) {\r\n key = hash;\r\n hash = {};\r\n hash[key] = val;\r\n }\r\n\r\n // used as a getter: first argument is a string, second is undefined\r\n if (isString(hash)) {\r\n key = hash;\r\n if (nodeName === \"circle\") {\r\n key = { x: \"cx\", y: \"cy\" }[key] || key;\r\n }\r\n else if (key === \"strokeWidth\") {\r\n key = \"stroke-width\";\r\n }\r\n ret = attr(element, key) || wrapper[key] || 0;\r\n if (key !== \"d\" && key !== \"visibility\" && key !== \"fill\") {\r\n // 'd' is string in animation step\r\n ret = parseFloat(ret);\r\n }\r\n\r\n // setter\r\n }\r\n else {\r\n for (key in hash) {\r\n skipAttr = false; // reset\r\n value = hash[key];\r\n\r\n // check for a specific attribute setter\r\n result =\r\n attrSetters[key] && attrSetters[key].call(wrapper, value, key);\r\n\r\n if (result !== false) {\r\n if (result !== UNDEFINED) {\r\n value = result; // the attribute setter has returned a new value to set\r\n }\r\n\r\n // paths\r\n if (key === \"d\") {\r\n if (value && value.join) {\r\n // join path\r\n value = value.join(\" \");\r\n }\r\n if (/(NaN| {2}|^$)/.test(value)) {\r\n value = \"M 0 0\";\r\n }\r\n //wrapper.d = value; // shortcut for animations\r\n\r\n // update child tspans x values\r\n }\r\n else if (key === \"x\" && nodeName === \"text\") {\r\n for (i = 0; i < element.childNodes.length; i++) {\r\n child = element.childNodes[i];\r\n // if the x values are equal, the tspan represents a linebreak\r\n if (attr(child, \"x\") === attr(element, \"x\")) {\r\n //child.setAttribute('x', value);\r\n attr(child, \"x\", value);\r\n }\r\n }\r\n }\r\n else if (wrapper.rotation && (key === \"x\" || key === \"y\")) {\r\n doTransform = true;\r\n\r\n // apply gradients\r\n }\r\n else if (key === \"fill\") {\r\n value = renderer.color(value, element, key);\r\n\r\n // circle x and y\r\n }\r\n else if (nodeName === \"circle\" && (key === \"x\" || key === \"y\")) {\r\n key = { x: \"cx\", y: \"cy\" }[key] || key;\r\n\r\n // rectangle border radius\r\n }\r\n else if (nodeName === \"rect\" && key === \"r\") {\r\n attr(element, {\r\n rx: value,\r\n ry: value\r\n });\r\n skipAttr = true;\r\n\r\n // translation and text rotation\r\n }\r\n else if (\r\n key === \"translateX\" ||\r\n key === \"translateY\" ||\r\n key === \"rotation\" ||\r\n key === \"verticalAlign\" ||\r\n key === \"scaleX\" ||\r\n key === \"scaleY\"\r\n ) {\r\n doTransform = true;\r\n skipAttr = true;\r\n\r\n // apply opacity as subnode (required by legacy WebKit and Batik)\r\n }\r\n else if (key === \"stroke\") {\r\n value = renderer.color(value, element, key);\r\n\r\n // emulate VML's dashstyle implementation\r\n }\r\n else if (key === \"dashstyle\") {\r\n key = \"stroke-dasharray\";\r\n value = value && value.toLowerCase();\r\n if (value === \"solid\") {\r\n value = NONE;\r\n }\r\n else if (value) {\r\n value = value\r\n .replace(\"shortdashdotdot\", \"3,1,1,1,1,1,\")\r\n .replace(\"shortdashdot\", \"3,1,1,1\")\r\n .replace(\"shortdot\", \"1,1,\")\r\n .replace(\"shortdash\", \"3,1,\")\r\n .replace(\"longdash\", \"8,3,\")\r\n .replace(/dot/g, \"1,3,\")\r\n .replace(\"dash\", \"4,3,\")\r\n .replace(/,$/, \"\")\r\n .split(\",\"); // ending comma\r\n\r\n i = value.length;\r\n while (i--) {\r\n value[i] =\r\n pInt(value[i]) *\r\n pick(hash[\"stroke-width\"], wrapper[\"stroke-width\"]);\r\n }\r\n value = value.join(\",\");\r\n }\r\n\r\n // IE9/MooTools combo: MooTools returns objects instead of numbers and IE9 Beta 2\r\n // is unable to cast them. Test again with final IE9.\r\n }\r\n else if (key === \"width\") {\r\n value = pInt(value);\r\n\r\n // Text alignment\r\n }\r\n else if (key === \"align\") {\r\n key = \"text-anchor\";\r\n value = { left: \"start\", center: \"middle\", right: \"end\" }[value];\r\n\r\n // Title requires a subnode, #431\r\n }\r\n else if (key === \"title\") {\r\n titleNode = element.getElementsByTagName(\"title\")[0];\r\n if (!titleNode) {\r\n titleNode = doc.createElementNS(SVG_NS, \"title\");\r\n element.appendChild(titleNode);\r\n }\r\n titleNode.textContent = value;\r\n }\r\n\r\n // jQuery animate changes case\r\n if (key === \"strokeWidth\") {\r\n key = \"stroke-width\";\r\n }\r\n\r\n // In Chrome/Win < 6 as well as Batik, the stroke attribute can't be set when the stroke-\r\n // width is 0. #1369\r\n if (key === \"stroke-width\" || key === \"stroke\") {\r\n wrapper[key] = value;\r\n // Only apply the stroke attribute if the stroke width is defined and larger than 0\r\n if (wrapper.stroke && wrapper[\"stroke-width\"]) {\r\n attr(element, \"stroke\", wrapper.stroke);\r\n attr(element, \"stroke-width\", wrapper[\"stroke-width\"]);\r\n wrapper.hasStroke = true;\r\n }\r\n else if (\r\n key === \"stroke-width\" &&\r\n value === 0 &&\r\n wrapper.hasStroke\r\n ) {\r\n element.removeAttribute(\"stroke\");\r\n wrapper.hasStroke = false;\r\n }\r\n skipAttr = true;\r\n }\r\n\r\n // symbols\r\n if (\r\n wrapper.symbolName &&\r\n /^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)/.test(key)\r\n ) {\r\n if (!hasSetSymbolSize) {\r\n wrapper.symbolAttr(hash);\r\n hasSetSymbolSize = true;\r\n }\r\n skipAttr = true;\r\n }\r\n\r\n // let the shadow follow the main element\r\n if (\r\n shadows &&\r\n /^(width|height|visibility|x|y|d|transform|cx|cy|r)$/.test(key)\r\n ) {\r\n i = shadows.length;\r\n while (i--) {\r\n attr(\r\n shadows[i],\r\n key,\r\n key === \"height\"\r\n ? mathMax(value - (shadows[i].cutHeight || 0), 0)\r\n : value\r\n );\r\n }\r\n }\r\n\r\n // validate heights\r\n if (\r\n (key === \"width\" || key === \"height\") &&\r\n nodeName === \"rect\" &&\r\n value < 0\r\n ) {\r\n value = 0;\r\n }\r\n\r\n // Record for animation and quick access without polling the DOM\r\n wrapper[key] = value;\r\n\r\n if (key === \"text\") {\r\n // Delete bBox memo when the text changes\r\n if (value !== wrapper.textStr) {\r\n delete wrapper.bBox;\r\n }\r\n wrapper.textStr = value;\r\n if (wrapper.added) {\r\n renderer.buildText(wrapper);\r\n }\r\n }\r\n else if (!skipAttr) {\r\n attr(element, key, value);\r\n }\r\n }\r\n }\r\n\r\n // Update transform. Do this outside the loop to prevent redundant updating for batch setting\r\n // of attributes.\r\n if (doTransform) {\r\n wrapper.updateTransform();\r\n }\r\n }\r\n\r\n return ret;\r\n },\r\n\r\n /**\r\n * Add a class name to an element\r\n */\r\n addClass: function(className) {\r\n var element = this.element,\r\n currentClassName = attr(element, \"class\") || \"\";\r\n\r\n if (currentClassName.indexOf(className) === -1) {\r\n attr(element, \"class\", currentClassName + \" \" + className);\r\n }\r\n return this;\r\n },\r\n /* hasClass and removeClass are not (yet) needed\r\n\thasClass: function (className) {\r\n\t\treturn attr(this.element, 'class').indexOf(className) !== -1;\r\n\t},\r\n\tremoveClass: function (className) {\r\n\t\tattr(this.element, 'class', attr(this.element, 'class').replace(className, ''));\r\n\t\treturn this;\r\n\t},\r\n\t*/\r\n\r\n /**\r\n * If one of the symbol size affecting parameters are changed,\r\n * check all the others only once for each call to an element's\r\n * .attr() method\r\n * @param {Object} hash\r\n */\r\n symbolAttr: function(hash) {\r\n var wrapper = this;\r\n\r\n each(\r\n [\r\n \"x\",\r\n \"y\",\r\n \"r\",\r\n \"start\",\r\n \"end\",\r\n \"width\",\r\n \"height\",\r\n \"innerR\",\r\n \"anchorX\",\r\n \"anchorY\"\r\n ],\r\n function(key) {\r\n wrapper[key] = pick(hash[key], wrapper[key]);\r\n }\r\n );\r\n\r\n wrapper.attr({\r\n d: wrapper.renderer.symbols[wrapper.symbolName](\r\n wrapper.x,\r\n wrapper.y,\r\n wrapper.width,\r\n wrapper.height,\r\n wrapper\r\n )\r\n });\r\n },\r\n\r\n /**\r\n * Apply a clipping path to this object\r\n * @param {String} id\r\n */\r\n clip: function(clipRect) {\r\n return this.attr(\r\n \"clip-path\",\r\n clipRect ? \"url(\" + this.renderer.url + \"#\" + clipRect.id + \")\" : NONE\r\n );\r\n },\r\n\r\n /**\r\n * Calculate the coordinates needed for drawing a rectangle crisply and return the\r\n * calculated attributes\r\n * @param {Number} strokeWidth\r\n * @param {Number} x\r\n * @param {Number} y\r\n * @param {Number} width\r\n * @param {Number} height\r\n */\r\n crisp: function(strokeWidth, x, y, width, height) {\r\n var wrapper = this,\r\n key,\r\n attribs = {},\r\n values = {},\r\n normalizer;\r\n\r\n strokeWidth =\r\n strokeWidth ||\r\n wrapper.strokeWidth ||\r\n (wrapper.attr && wrapper.attr(\"stroke-width\")) ||\r\n 0;\r\n normalizer = (mathRound(strokeWidth) % 2) / 2; // mathRound because strokeWidth can sometimes have roundoff errors\r\n\r\n // normalize for crisp edges\r\n values.x = mathFloor(x || wrapper.x || 0) + normalizer;\r\n values.y = mathFloor(y || wrapper.y || 0) + normalizer;\r\n values.width = mathFloor((width || wrapper.width || 0) - 2 * normalizer);\r\n values.height = mathFloor(\r\n (height || wrapper.height || 0) - 2 * normalizer\r\n );\r\n values.strokeWidth = strokeWidth;\r\n\r\n for (key in values) {\r\n if (wrapper[key] !== values[key]) {\r\n // only set attribute if changed\r\n wrapper[key] = attribs[key] = values[key];\r\n }\r\n }\r\n\r\n return attribs;\r\n },\r\n\r\n /**\r\n * Set styles for the element\r\n * @param {Object} styles\r\n */\r\n css: function(styles) {\r\n /*jslint unparam: true*/ /* allow unused param a in the regexp function below */\r\n var elemWrapper = this,\r\n elem = elemWrapper.element,\r\n textWidth = (elemWrapper.textWidth =\r\n styles &&\r\n styles.width &&\r\n elem.nodeName.toLowerCase() === \"text\" &&\r\n pInt(styles.width)),\r\n n,\r\n serializedCss = \"\",\r\n hyphenate = function(a, b) {\r\n return \"-\" + b.toLowerCase();\r\n };\r\n /*jslint unparam: false*/\r\n\r\n // convert legacy\r\n if (styles && styles.color) {\r\n styles.fill = styles.color;\r\n }\r\n\r\n // Merge the new styles with the old ones\r\n styles = extend(elemWrapper.styles, styles);\r\n\r\n // store object\r\n elemWrapper.styles = styles;\r\n\r\n if (textWidth) {\r\n delete styles.width;\r\n }\r\n\r\n // serialize and set style attribute\r\n if (isIE && !hasSVG) {\r\n css(elemWrapper.element, styles);\r\n }\r\n else {\r\n for (n in styles) {\r\n serializedCss +=\r\n n.replace(/([A-Z])/g, hyphenate) + \":\" + styles[n] + \";\";\r\n }\r\n attr(elem, \"style\", serializedCss); // #1881\r\n }\r\n\r\n // re-build text\r\n if (textWidth && elemWrapper.added) {\r\n elemWrapper.renderer.buildText(elemWrapper);\r\n }\r\n\r\n return elemWrapper;\r\n },\r\n\r\n /**\r\n * Add an event listener\r\n * @param {String} eventType\r\n * @param {Function} handler\r\n */\r\n on: function(eventType, handler) {\r\n var svgElement = this,\r\n element = svgElement.element;\r\n\r\n // touch\r\n if (hasTouch && eventType === \"click\") {\r\n element.ontouchstart = function(e) {\r\n svgElement.touchEventFired = Date.now();\r\n e.preventDefault();\r\n handler.call(element, e);\r\n };\r\n element.onclick = function(e) {\r\n if (\r\n userAgent.indexOf(\"Android\") === -1 ||\r\n Date.now() - (svgElement.touchEventFired || 0) > 1100\r\n ) {\r\n // #2269\r\n handler.call(element, e);\r\n }\r\n };\r\n }\r\n else {\r\n // simplest possible event model for internal use\r\n element[\"on\" + eventType] = handler;\r\n }\r\n return this;\r\n },\r\n\r\n /**\r\n * Set the coordinates needed to draw a consistent radial gradient across\r\n * pie slices regardless of positioning inside the chart. The format is\r\n * [centerX, centerY, diameter] in pixels.\r\n */\r\n setRadialReference: function(coordinates) {\r\n this.element.radialReference = coordinates;\r\n return this;\r\n },\r\n\r\n /**\r\n * Move an object and its children by x and y values\r\n * @param {Number} x\r\n * @param {Number} y\r\n */\r\n translate: function(x, y) {\r\n return this.attr({\r\n translateX: x,\r\n translateY: y\r\n });\r\n },\r\n\r\n /**\r\n * Invert a group, rotate and flip\r\n */\r\n invert: function() {\r\n var wrapper = this;\r\n wrapper.inverted = true;\r\n wrapper.updateTransform();\r\n return wrapper;\r\n },\r\n\r\n /**\r\n * Apply CSS to HTML elements. This is used in text within SVG rendering and\r\n * by the VML renderer\r\n */\r\n htmlCss: function(styles) {\r\n var wrapper = this,\r\n element = wrapper.element,\r\n textWidth = styles && element.tagName === \"SPAN\" && styles.width;\r\n\r\n if (textWidth) {\r\n delete styles.width;\r\n wrapper.textWidth = textWidth;\r\n wrapper.updateTransform();\r\n }\r\n\r\n wrapper.styles = extend(wrapper.styles, styles);\r\n css(wrapper.element, styles);\r\n\r\n return wrapper;\r\n },\r\n\r\n /**\r\n * VML and useHTML method for calculating the bounding box based on offsets\r\n * @param {Boolean} refresh Whether to force a fresh value from the DOM or to\r\n * use the cached value\r\n *\r\n * @return {Object} A hash containing values for x, y, width and height\r\n */\r\n\r\n htmlGetBBox: function() {\r\n var wrapper = this,\r\n element = wrapper.element,\r\n bBox = wrapper.bBox;\r\n\r\n // faking getBBox in exported SVG in legacy IE\r\n if (!bBox) {\r\n // faking getBBox in exported SVG in legacy IE (is this a duplicate of the fix for #1079?)\r\n if (element.nodeName === \"text\") {\r\n element.style.position = ABSOLUTE;\r\n }\r\n\r\n bBox = wrapper.bBox = {\r\n x: element.offsetLeft,\r\n y: element.offsetTop,\r\n width: element.offsetWidth,\r\n height: element.offsetHeight\r\n };\r\n }\r\n\r\n return bBox;\r\n },\r\n\r\n /**\r\n * VML override private method to update elements based on internal\r\n * properties based on SVG transform\r\n */\r\n htmlUpdateTransform: function() {\r\n // aligning non added elements is expensive\r\n if (!this.added) {\r\n this.alignOnAdd = true;\r\n return;\r\n }\r\n\r\n var wrapper = this,\r\n renderer = wrapper.renderer,\r\n elem = wrapper.element,\r\n translateX = wrapper.translateX || 0,\r\n translateY = wrapper.translateY || 0,\r\n x = wrapper.x || 0,\r\n y = wrapper.y || 0,\r\n align = wrapper.textAlign || \"left\",\r\n alignCorrection = { left: 0, center: 0.5, right: 1 }[align],\r\n nonLeft = align && align !== \"left\",\r\n shadows = wrapper.shadows;\r\n\r\n // apply translate\r\n css(elem, {\r\n marginLeft: translateX,\r\n marginTop: translateY\r\n });\r\n if (shadows) {\r\n // used in labels/tooltip\r\n each(shadows, function(shadow) {\r\n css(shadow, {\r\n marginLeft: translateX + 1,\r\n marginTop: translateY + 1\r\n });\r\n });\r\n }\r\n\r\n // apply inversion\r\n if (wrapper.inverted) {\r\n // wrapper is a group\r\n each(elem.childNodes, function(child) {\r\n renderer.invertChild(child, elem);\r\n });\r\n }\r\n\r\n if (elem.tagName === \"SPAN\") {\r\n var width,\r\n height,\r\n rotation = wrapper.rotation,\r\n baseline,\r\n radians = 0,\r\n costheta = 1,\r\n sintheta = 0,\r\n quad,\r\n textWidth = pInt(wrapper.textWidth),\r\n xCorr = wrapper.xCorr || 0,\r\n yCorr = wrapper.yCorr || 0,\r\n currentTextTransform = [\r\n rotation,\r\n align,\r\n elem.innerHTML,\r\n wrapper.textWidth\r\n ].join(\",\");\r\n\r\n if (currentTextTransform !== wrapper.cTT) {\r\n // do the calculations and DOM access only if properties changed\r\n\r\n if (defined(rotation)) {\r\n radians = rotation * deg2rad; // deg to rad\r\n costheta = mathCos(radians);\r\n sintheta = mathSin(radians);\r\n\r\n wrapper.setSpanRotation(rotation, sintheta, costheta);\r\n }\r\n\r\n width = pick(wrapper.elemWidth, elem.offsetWidth);\r\n height = pick(wrapper.elemHeight, elem.offsetHeight);\r\n\r\n // update textWidth\r\n if (\r\n width > textWidth &&\r\n /[ \\-]/.test(elem.textContent || elem.innerText)\r\n ) {\r\n // #983, #1254\r\n css(elem, {\r\n width: textWidth + PX,\r\n display: \"block\",\r\n whiteSpace: \"normal\"\r\n });\r\n width = textWidth;\r\n }\r\n\r\n // correct x and y\r\n baseline = renderer.fontMetrics(elem.style.fontSize).b;\r\n xCorr = costheta < 0 && -width;\r\n yCorr = sintheta < 0 && -height;\r\n\r\n // correct for baseline and corners spilling out after rotation\r\n quad = costheta * sintheta < 0;\r\n xCorr +=\r\n sintheta *\r\n baseline *\r\n (quad ? 1 - alignCorrection : alignCorrection);\r\n yCorr -=\r\n costheta *\r\n baseline *\r\n (rotation ? (quad ? alignCorrection : 1 - alignCorrection) : 1);\r\n\r\n // correct for the length/height of the text\r\n if (nonLeft) {\r\n xCorr -= width * alignCorrection * (costheta < 0 ? -1 : 1);\r\n if (rotation) {\r\n yCorr -= height * alignCorrection * (sintheta < 0 ? -1 : 1);\r\n }\r\n css(elem, {\r\n textAlign: align\r\n });\r\n }\r\n\r\n // record correction\r\n wrapper.xCorr = xCorr;\r\n wrapper.yCorr = yCorr;\r\n }\r\n\r\n // apply position with correction\r\n css(elem, {\r\n left: x + xCorr + PX,\r\n top: y + yCorr + PX\r\n });\r\n\r\n // force reflow in webkit to apply the left and top on useHTML element (#1249)\r\n if (isWebKit) {\r\n height = elem.offsetHeight; // assigned to height for JSLint purpose\r\n }\r\n\r\n // record current text transform\r\n wrapper.cTT = currentTextTransform;\r\n }\r\n },\r\n\r\n /**\r\n * Set the rotation of an individual HTML span\r\n */\r\n setSpanRotation: function(rotation) {\r\n var rotationStyle = {},\r\n cssTransformKey = isIE\r\n ? \"-ms-transform\"\r\n : isWebKit\r\n ? \"-webkit-transform\"\r\n : isFirefox\r\n ? \"MozTransform\"\r\n : isOpera\r\n ? \"-o-transform\"\r\n : \"\";\r\n\r\n rotationStyle[cssTransformKey] = rotationStyle.transform =\r\n \"rotate(\" + rotation + \"deg)\";\r\n css(this.element, rotationStyle);\r\n },\r\n\r\n /**\r\n * Private method to update the transform attribute based on internal\r\n * properties\r\n */\r\n updateTransform: function() {\r\n var wrapper = this,\r\n translateX = wrapper.translateX || 0,\r\n translateY = wrapper.translateY || 0,\r\n scaleX = wrapper.scaleX,\r\n scaleY = wrapper.scaleY,\r\n inverted = wrapper.inverted,\r\n rotation = wrapper.rotation,\r\n transform;\r\n\r\n // flipping affects translate as adjustment for flipping around the group's axis\r\n if (inverted) {\r\n translateX += wrapper.attr(\"width\");\r\n translateY += wrapper.attr(\"height\");\r\n }\r\n\r\n // Apply translate. Nearly all transformed elements have translation, so instead\r\n // of checking for translate = 0, do it always (#1767, #1846).\r\n transform = [\"translate(\" + translateX + \",\" + translateY + \")\"];\r\n\r\n // apply rotation\r\n if (inverted) {\r\n transform.push(\"rotate(90) scale(-1,1)\");\r\n }\r\n else if (rotation) {\r\n // text rotation\r\n transform.push(\r\n \"rotate(\" +\r\n rotation +\r\n \" \" +\r\n (wrapper.x || 0) +\r\n \" \" +\r\n (wrapper.y || 0) +\r\n \")\"\r\n );\r\n }\r\n\r\n // apply scale\r\n if (defined(scaleX) || defined(scaleY)) {\r\n transform.push(\r\n \"scale(\" + pick(scaleX, 1) + \" \" + pick(scaleY, 1) + \")\"\r\n );\r\n }\r\n\r\n if (transform.length) {\r\n attr(wrapper.element, \"transform\", transform.join(\" \"));\r\n }\r\n },\r\n /**\r\n * Bring the element to the front\r\n */\r\n toFront: function() {\r\n var element = this.element;\r\n element.parentNode.appendChild(element);\r\n return this;\r\n },\r\n\r\n /**\r\n * Break down alignment options like align, verticalAlign, x and y\r\n * to x and y relative to the chart.\r\n *\r\n * @param {Object} alignOptions\r\n * @param {Boolean} alignByTranslate\r\n * @param {String[Object} box The box to align to, needs a width and height. When the\r\n * box is a string, it refers to an object in the Renderer. For example, when\r\n * box is 'spacingBox', it refers to Renderer.spacingBox which holds width, height\r\n * x and y properties.\r\n *\r\n */\r\n align: function(alignOptions, alignByTranslate, box) {\r\n var align,\r\n vAlign,\r\n x,\r\n y,\r\n attribs = {},\r\n alignTo,\r\n renderer = this.renderer,\r\n alignedObjects = renderer.alignedObjects;\r\n\r\n // First call on instanciate\r\n if (alignOptions) {\r\n this.alignOptions = alignOptions;\r\n this.alignByTranslate = alignByTranslate;\r\n if (!box || isString(box)) {\r\n // boxes other than renderer handle this internally\r\n this.alignTo = alignTo = box || \"renderer\";\r\n erase(alignedObjects, this); // prevent duplicates, like legendGroup after resize\r\n alignedObjects.push(this);\r\n box = null; // reassign it below\r\n }\r\n\r\n // When called on resize, no arguments are supplied\r\n }\r\n else {\r\n alignOptions = this.alignOptions;\r\n alignByTranslate = this.alignByTranslate;\r\n alignTo = this.alignTo;\r\n }\r\n\r\n box = pick(box, renderer[alignTo], renderer);\r\n\r\n // Assign variables\r\n align = alignOptions.align;\r\n vAlign = alignOptions.verticalAlign;\r\n x = (box.x || 0) + (alignOptions.x || 0); // default: left align\r\n y = (box.y || 0) + (alignOptions.y || 0); // default: top align\r\n\r\n // Align\r\n if (align === \"right\" || align === \"center\") {\r\n x +=\r\n (box.width - (alignOptions.width || 0)) /\r\n { right: 1, center: 2 }[align];\r\n }\r\n attribs[alignByTranslate ? \"translateX\" : \"x\"] = mathRound(x);\r\n\r\n // Vertical align\r\n if (vAlign === \"bottom\" || vAlign === \"middle\") {\r\n y +=\r\n (box.height - (alignOptions.height || 0)) /\r\n ({ bottom: 1, middle: 2 }[vAlign] || 1);\r\n }\r\n attribs[alignByTranslate ? \"translateY\" : \"y\"] = mathRound(y);\r\n\r\n // Animate only if already placed\r\n this[this.placed ? \"animate\" : \"attr\"](attribs);\r\n this.placed = true;\r\n this.alignAttr = attribs;\r\n\r\n return this;\r\n },\r\n\r\n /**\r\n * Get the bounding box (width, height, x and y) for the element\r\n */\r\n getBBox: function() {\r\n var wrapper = this,\r\n bBox = wrapper.bBox,\r\n renderer = wrapper.renderer,\r\n width,\r\n height,\r\n rotation = wrapper.rotation,\r\n element = wrapper.element,\r\n styles = wrapper.styles,\r\n rad = rotation * deg2rad;\r\n\r\n if (!bBox) {\r\n // SVG elements\r\n if (element.namespaceURI === SVG_NS || renderer.forExport) {\r\n try {\r\n // Fails in Firefox if the container has display: none.\r\n\r\n bBox = element.getBBox\r\n ? // SVG: use extend because IE9 is not allowed to change width and height in case\r\n // of rotation (below)\r\n extend({}, element.getBBox())\r\n : // Canvas renderer and legacy IE in export mode\r\n {\r\n width: element.offsetWidth,\r\n height: element.offsetHeight\r\n };\r\n }\r\n catch (e) {}\r\n\r\n // If the bBox is not set, the try-catch block above failed. The other condition\r\n // is for Opera that returns a width of -Infinity on hidden elements.\r\n if (!bBox || bBox.width < 0) {\r\n bBox = { width: 0, height: 0 };\r\n }\r\n\r\n // VML Renderer or useHTML within SVG\r\n }\r\n else {\r\n bBox = wrapper.htmlGetBBox();\r\n }\r\n\r\n // True SVG elements as well as HTML elements in modern browsers using the .useHTML option\r\n // need to compensated for rotation\r\n if (renderer.isSVG) {\r\n width = bBox.width;\r\n height = bBox.height;\r\n\r\n // Workaround for wrong bounding box in IE9 and IE10 (#1101, #1505, #1669)\r\n if (\r\n isIE &&\r\n styles &&\r\n styles.fontSize === \"11px\" &&\r\n height.toPrecision(3) === \"22.7\"\r\n ) {\r\n bBox.height = height = 14;\r\n }\r\n\r\n // Adjust for rotated text\r\n if (rotation) {\r\n bBox.width =\r\n mathAbs(height * mathSin(rad)) + mathAbs(width * mathCos(rad));\r\n bBox.height =\r\n mathAbs(height * mathCos(rad)) + mathAbs(width * mathSin(rad));\r\n }\r\n }\r\n\r\n wrapper.bBox = bBox;\r\n }\r\n return bBox;\r\n },\r\n\r\n /**\r\n * Show the element\r\n */\r\n show: function() {\r\n return this.attr({ visibility: VISIBLE });\r\n },\r\n\r\n /**\r\n * Hide the element\r\n */\r\n hide: function() {\r\n return this.attr({ visibility: HIDDEN });\r\n },\r\n\r\n fadeOut: function(duration) {\r\n var elemWrapper = this;\r\n elemWrapper.animate(\r\n {\r\n opacity: 0\r\n },\r\n {\r\n duration: duration || 150,\r\n complete: function() {\r\n elemWrapper.hide();\r\n }\r\n }\r\n );\r\n },\r\n\r\n /**\r\n * Add the element\r\n * @param {Object|Undefined} parent Can be an element, an element wrapper or undefined\r\n * to append the element to the renderer.box.\r\n */\r\n add: function(parent) {\r\n var renderer = this.renderer,\r\n parentWrapper = parent || renderer,\r\n parentNode = parentWrapper.element || renderer.box,\r\n childNodes = parentNode.childNodes,\r\n element = this.element,\r\n zIndex = attr(element, \"zIndex\"),\r\n otherElement,\r\n otherZIndex,\r\n i,\r\n inserted;\r\n\r\n if (parent) {\r\n this.parentGroup = parent;\r\n }\r\n\r\n // mark as inverted\r\n this.parentInverted = parent && parent.inverted;\r\n\r\n // build formatted text\r\n if (this.textStr !== undefined) {\r\n renderer.buildText(this);\r\n }\r\n\r\n // mark the container as having z indexed children\r\n if (zIndex) {\r\n parentWrapper.handleZ = true;\r\n zIndex = pInt(zIndex);\r\n }\r\n\r\n // insert according to this and other elements' zIndex\r\n if (parentWrapper.handleZ) {\r\n // this element or any of its siblings has a z index\r\n for (i = 0; i < childNodes.length; i++) {\r\n otherElement = childNodes[i];\r\n otherZIndex = attr(otherElement, \"zIndex\");\r\n if (\r\n otherElement !== element &&\r\n // insert before the first element with a higher zIndex\r\n (pInt(otherZIndex) > zIndex ||\r\n // if no zIndex given, insert before the first element with a zIndex\r\n (!defined(zIndex) && defined(otherZIndex)))\r\n ) {\r\n parentNode.insertBefore(element, otherElement);\r\n inserted = true;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // default: append at the end\r\n if (!inserted) {\r\n parentNode.appendChild(element);\r\n }\r\n\r\n // mark as added\r\n this.added = true;\r\n\r\n // fire an event for internal hooks\r\n fireEvent(this, \"add\");\r\n\r\n return this;\r\n },\r\n\r\n /**\r\n * Removes a child either by removeChild or move to garbageBin.\r\n * Issue 490; in VML removeChild results in Orphaned nodes according to sIEve, discardElement does not.\r\n */\r\n safeRemoveChild: function(element) {\r\n var parentNode = element.parentNode;\r\n if (parentNode) {\r\n parentNode.removeChild(element);\r\n }\r\n },\r\n\r\n /**\r\n * Destroy the element and element wrapper\r\n */\r\n destroy: function() {\r\n var wrapper = this,\r\n element = wrapper.element || {},\r\n shadows = wrapper.shadows,\r\n parentToClean =\r\n wrapper.renderer.isSVG &&\r\n element.nodeName === \"SPAN\" &&\r\n wrapper.parentGroup,\r\n grandParent,\r\n key,\r\n i;\r\n\r\n // remove events\r\n element.onclick = element.onmouseout = element.onmouseover = element.onmousemove = element.point = null;\r\n stop(wrapper); // stop running animations\r\n\r\n if (wrapper.clipPath) {\r\n wrapper.clipPath = wrapper.clipPath.destroy();\r\n }\r\n\r\n // Destroy stops in case this is a gradient object\r\n if (wrapper.stops) {\r\n for (i = 0; i < wrapper.stops.length; i++) {\r\n wrapper.stops[i] = wrapper.stops[i].destroy();\r\n }\r\n wrapper.stops = null;\r\n }\r\n\r\n // remove element\r\n wrapper.safeRemoveChild(element);\r\n\r\n // destroy shadows\r\n if (shadows) {\r\n each(shadows, function(shadow) {\r\n wrapper.safeRemoveChild(shadow);\r\n });\r\n }\r\n\r\n // In case of useHTML, clean up empty containers emulating SVG groups (#1960, #2393).\r\n while (parentToClean && parentToClean.div.childNodes.length === 0) {\r\n grandParent = parentToClean.parentGroup;\r\n wrapper.safeRemoveChild(parentToClean.div);\r\n delete parentToClean.div;\r\n parentToClean = grandParent;\r\n }\r\n\r\n // remove from alignObjects\r\n if (wrapper.alignTo) {\r\n erase(wrapper.renderer.alignedObjects, wrapper);\r\n }\r\n\r\n for (key in wrapper) {\r\n delete wrapper[key];\r\n }\r\n\r\n return null;\r\n },\r\n\r\n /**\r\n * Add a shadow to the element. Must be done after the element is added to the DOM\r\n * @param {Boolean|Object} shadowOptions\r\n */\r\n shadow: function(shadowOptions, group, cutOff) {\r\n var shadows = [],\r\n i,\r\n shadow,\r\n element = this.element,\r\n strokeWidth,\r\n shadowWidth,\r\n shadowElementOpacity,\r\n // compensate for inverted plot area\r\n transform;\r\n\r\n if (shadowOptions) {\r\n shadowWidth = pick(shadowOptions.width, 3);\r\n shadowElementOpacity = (shadowOptions.opacity || 0.15) / shadowWidth;\r\n transform = this.parentInverted\r\n ? \"(-1,-1)\"\r\n : \"(\" +\r\n pick(shadowOptions.offsetX, 1) +\r\n \", \" +\r\n pick(shadowOptions.offsetY, 1) +\r\n \")\";\r\n for (i = 1; i <= shadowWidth; i++) {\r\n shadow = element.cloneNode(0);\r\n strokeWidth = shadowWidth * 2 + 1 - 2 * i;\r\n attr(shadow, {\r\n isShadow: \"true\",\r\n stroke: shadowOptions.color || \"black\",\r\n \"stroke-opacity\": shadowElementOpacity * i,\r\n \"stroke-width\": strokeWidth,\r\n transform: \"translate\" + transform,\r\n fill: NONE\r\n });\r\n if (cutOff) {\r\n attr(\r\n shadow,\r\n \"height\",\r\n mathMax(attr(shadow, \"height\") - strokeWidth, 0)\r\n );\r\n shadow.cutHeight = strokeWidth;\r\n }\r\n\r\n if (group) {\r\n group.element.appendChild(shadow);\r\n }\r\n else {\r\n element.parentNode.insertBefore(shadow, element);\r\n }\r\n\r\n shadows.push(shadow);\r\n }\r\n\r\n this.shadows = shadows;\r\n }\r\n return this;\r\n }\r\n };\r\n\r\n /**\r\n * The default SVG renderer\r\n */\r\n var SVGRenderer = function() {\r\n this.init.apply(this, arguments);\r\n };\r\n SVGRenderer.prototype = {\r\n Element: SVGElement,\r\n\r\n /**\r\n * Initialize the SVGRenderer\r\n * @param {Object} container\r\n * @param {Number} width\r\n * @param {Number} height\r\n * @param {Boolean} forExport\r\n */\r\n init: function(container, width, height, forExport) {\r\n var renderer = this,\r\n loc = location,\r\n boxWrapper,\r\n element,\r\n desc;\r\n\r\n boxWrapper = renderer.createElement(\"svg\").attr({\r\n version: \"1.1\"\r\n });\r\n element = boxWrapper.element;\r\n container.appendChild(element);\r\n\r\n // For browsers other than IE, add the namespace attribute (#1978)\r\n if (container.innerHTML.indexOf(\"xmlns\") === -1) {\r\n attr(element, \"xmlns\", SVG_NS);\r\n }\r\n\r\n // object properties\r\n renderer.isSVG = true;\r\n renderer.box = element;\r\n renderer.boxWrapper = boxWrapper;\r\n renderer.alignedObjects = [];\r\n\r\n // Page url used for internal references. #24, #672, #1070\r\n renderer.url =\r\n (isFirefox || isWebKit) && doc.getElementsByTagName(\"base\").length\r\n ? loc.href\r\n .replace(/#.*?$/, \"\") // remove the hash\r\n .replace(/([\\('\\)])/g, \"\\\\$1\") // escape parantheses and quotes\r\n .replace(/ /g, \"%20\") // replace spaces (needed for Safari only)\r\n : \"\";\r\n\r\n // Add description\r\n desc = this.createElement(\"desc\").add();\r\n desc.element.appendChild(\r\n doc.createTextNode(\"Created with \" + PRODUCT + \" \" + VERSION)\r\n );\r\n\r\n renderer.defs = this.createElement(\"defs\").add();\r\n renderer.forExport = forExport;\r\n renderer.gradients = {}; // Object where gradient SvgElements are stored\r\n\r\n renderer.setSize(width, height, false);\r\n\r\n // Issue 110 workaround:\r\n // In Firefox, if a div is positioned by percentage, its pixel position may land\r\n // between pixels. The container itself doesn't display this, but an SVG element\r\n // inside this container will be drawn at subpixel precision. In order to draw\r\n // sharp lines, this must be compensated for. This doesn't seem to work inside\r\n // iframes though (like in jsFiddle).\r\n var subPixelFix, rect;\r\n if (isFirefox && container.getBoundingClientRect) {\r\n renderer.subPixelFix = subPixelFix = function() {\r\n css(container, { left: 0, top: 0 });\r\n rect = container.getBoundingClientRect();\r\n css(container, {\r\n left: mathCeil(rect.left) - rect.left + PX,\r\n top: mathCeil(rect.top) - rect.top + PX\r\n });\r\n };\r\n\r\n // run the fix now\r\n subPixelFix();\r\n\r\n // run it on resize\r\n addEvent(win, \"resize\", subPixelFix);\r\n }\r\n },\r\n\r\n /**\r\n * Detect whether the renderer is hidden. This happens when one of the parent elements\r\n * has display: none. #608.\r\n */\r\n isHidden: function() {\r\n return !this.boxWrapper.getBBox().width;\r\n },\r\n\r\n /**\r\n * Destroys the renderer and its allocated members.\r\n */\r\n destroy: function() {\r\n var renderer = this,\r\n rendererDefs = renderer.defs;\r\n renderer.box = null;\r\n renderer.boxWrapper = renderer.boxWrapper.destroy();\r\n\r\n // Call destroy on all gradient elements\r\n destroyObjectProperties(renderer.gradients || {});\r\n renderer.gradients = null;\r\n\r\n // Defs are null in VMLRenderer\r\n // Otherwise, destroy them here.\r\n if (rendererDefs) {\r\n renderer.defs = rendererDefs.destroy();\r\n }\r\n\r\n // Remove sub pixel fix handler\r\n // We need to check that there is a handler, otherwise all functions that are registered for event 'resize' are removed\r\n // See issue #982\r\n if (renderer.subPixelFix) {\r\n removeEvent(win, \"resize\", renderer.subPixelFix);\r\n }\r\n\r\n renderer.alignedObjects = null;\r\n\r\n return null;\r\n },\r\n\r\n /**\r\n * Create a wrapper for an SVG element\r\n * @param {Object} nodeName\r\n */\r\n createElement: function(nodeName) {\r\n var wrapper = new this.Element();\r\n wrapper.init(this, nodeName);\r\n return wrapper;\r\n },\r\n\r\n /**\r\n * Dummy function for use in canvas renderer\r\n */\r\n draw: function() {},\r\n\r\n /**\r\n * Parse a simple HTML string into SVG tspans\r\n *\r\n * @param {Object} textNode The parent text SVG node\r\n */\r\n buildText: function(wrapper) {\r\n var textNode = wrapper.element,\r\n renderer = this,\r\n forExport = renderer.forExport,\r\n lines = pick(wrapper.textStr, \"\")\r\n .toString()\r\n .replace(/<(b|strong)>/g, '')\r\n .replace(/<(i|em)>/g, '')\r\n .replace(//g, \"\")\r\n .split(//g),\r\n childNodes = textNode.childNodes,\r\n styleRegex = /style=\"([^\"]+)\"/,\r\n hrefRegex = /href=\"(http[^\"]+)\"/,\r\n parentX = attr(textNode, \"x\"),\r\n textStyles = wrapper.styles,\r\n width = wrapper.textWidth,\r\n textLineHeight = textStyles && textStyles.lineHeight,\r\n i = childNodes.length;\r\n\r\n /// remove old text\r\n while (i--) {\r\n textNode.removeChild(childNodes[i]);\r\n }\r\n\r\n if (width && !wrapper.added) {\r\n this.box.appendChild(textNode); // attach it to the DOM to read offset width\r\n }\r\n\r\n // remove empty line at end\r\n if (lines[lines.length - 1] === \"\") {\r\n lines.pop();\r\n }\r\n\r\n // build the lines\r\n each(lines, function(line, lineNo) {\r\n var spans,\r\n spanNo = 0;\r\n\r\n line = line\r\n .replace(//g, \"|||\");\r\n spans = line.split(\"|||\");\r\n\r\n each(spans, function(span) {\r\n if (span !== \"\" || spans.length === 1) {\r\n var attributes = {},\r\n tspan = doc.createElementNS(SVG_NS, \"tspan\"),\r\n spanStyle; // #390\r\n if (styleRegex.test(span)) {\r\n spanStyle = span\r\n .match(styleRegex)[1]\r\n .replace(/(;| |^)color([ :])/, \"$1fill$2\");\r\n attr(tspan, \"style\", spanStyle);\r\n }\r\n if (hrefRegex.test(span) && !forExport) {\r\n // Not for export - #1529\r\n attr(\r\n tspan,\r\n \"onclick\",\r\n 'location.href=\"' + span.match(hrefRegex)[1] + '\"'\r\n );\r\n css(tspan, { cursor: \"pointer\" });\r\n }\r\n\r\n span = (span.replace(/<(.|\\n)*?>/g, \"\") || \" \")\r\n .replace(/</g, \"<\")\r\n .replace(/>/g, \">\");\r\n\r\n // Nested tags aren't supported, and cause crash in Safari (#1596)\r\n if (span !== \" \") {\r\n // add the text node\r\n tspan.appendChild(doc.createTextNode(span));\r\n\r\n if (!spanNo) {\r\n // first span in a line, align it to the left\r\n attributes.x = parentX;\r\n }\r\n else {\r\n attributes.dx = 0; // #16\r\n }\r\n\r\n // add attributes\r\n attr(tspan, attributes);\r\n\r\n // first span on subsequent line, add the line height\r\n if (!spanNo && lineNo) {\r\n // allow getting the right offset height in exporting in IE\r\n if (!hasSVG && forExport) {\r\n css(tspan, { display: \"block\" });\r\n }\r\n\r\n // Set the line height based on the font size of either\r\n // the text element or the tspan element\r\n attr(\r\n tspan,\r\n \"dy\",\r\n textLineHeight ||\r\n renderer.fontMetrics(\r\n /px$/.test(tspan.style.fontSize)\r\n ? tspan.style.fontSize\r\n : textStyles.fontSize\r\n ).h,\r\n // Safari 6.0.2 - too optimized for its own good (#1539)\r\n // TODO: revisit this with future versions of Safari\r\n isWebKit && tspan.offsetHeight\r\n );\r\n }\r\n\r\n // Append it\r\n textNode.appendChild(tspan);\r\n\r\n spanNo++;\r\n\r\n // check width and apply soft breaks\r\n if (width) {\r\n var words = span.replace(/([^\\^])-/g, \"$1- \").split(\" \"), // #1273\r\n tooLong,\r\n actualWidth,\r\n clipHeight = wrapper._clipHeight,\r\n rest = [],\r\n dy = pInt(textLineHeight || 16),\r\n softLineNo = 1,\r\n bBox;\r\n\r\n while (words.length || rest.length) {\r\n delete wrapper.bBox; // delete cache\r\n bBox = wrapper.getBBox();\r\n actualWidth = bBox.width;\r\n\r\n // Old IE cannot measure the actualWidth for SVG elements (#2314)\r\n if (!hasSVG && renderer.forExport) {\r\n actualWidth = renderer.measureSpanWidth(\r\n tspan.firstChild.data,\r\n wrapper.styles\r\n );\r\n }\r\n\r\n tooLong = actualWidth > width;\r\n if (!tooLong || words.length === 1) {\r\n // new line needed\r\n words = rest;\r\n rest = [];\r\n if (words.length) {\r\n softLineNo++;\r\n\r\n if (clipHeight && softLineNo * dy > clipHeight) {\r\n words = [\"...\"];\r\n wrapper.attr(\"title\", wrapper.textStr);\r\n }\r\n else {\r\n tspan = doc.createElementNS(SVG_NS, \"tspan\");\r\n attr(tspan, {\r\n dy: dy,\r\n x: parentX\r\n });\r\n if (spanStyle) {\r\n // #390\r\n attr(tspan, \"style\", spanStyle);\r\n }\r\n textNode.appendChild(tspan);\r\n\r\n if (actualWidth > width) {\r\n // a single word is pressing it out\r\n width = actualWidth;\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n // append to existing line tspan\r\n tspan.removeChild(tspan.firstChild);\r\n rest.unshift(words.pop());\r\n }\r\n if (words.length) {\r\n tspan.appendChild(\r\n doc.createTextNode(words.join(\" \").replace(/- /g, \"-\"))\r\n );\r\n }\r\n }\r\n }\r\n }\r\n }\r\n });\r\n });\r\n },\r\n\r\n /**\r\n * Create a button with preset states\r\n * @param {String} text\r\n * @param {Number} x\r\n * @param {Number} y\r\n * @param {Function} callback\r\n * @param {Object} normalState\r\n * @param {Object} hoverState\r\n * @param {Object} pressedState\r\n */\r\n button: function(\r\n text,\r\n x,\r\n y,\r\n callback,\r\n normalState,\r\n hoverState,\r\n pressedState,\r\n disabledState,\r\n shape\r\n ) {\r\n var label = this.label(\r\n text,\r\n x,\r\n y,\r\n shape,\r\n null,\r\n null,\r\n null,\r\n null,\r\n \"button\"\r\n ),\r\n curState = 0,\r\n stateOptions,\r\n stateStyle,\r\n normalStyle,\r\n hoverStyle,\r\n pressedStyle,\r\n disabledStyle,\r\n STYLE = \"style\",\r\n verticalGradient = { x1: 0, y1: 0, x2: 0, y2: 1 };\r\n\r\n // Normal state - prepare the attributes\r\n normalState = merge(\r\n {\r\n \"stroke-width\": 1,\r\n stroke: \"#CCCCCC\",\r\n fill: {\r\n linearGradient: verticalGradient,\r\n stops: [[0, \"#FEFEFE\"], [1, \"#F6F6F6\"]]\r\n },\r\n r: 2,\r\n padding: 5,\r\n style: {\r\n color: \"black\"\r\n }\r\n },\r\n normalState\r\n );\r\n normalStyle = normalState[STYLE];\r\n delete normalState[STYLE];\r\n\r\n // Hover state\r\n hoverState = merge(\r\n normalState,\r\n {\r\n stroke: \"#68A\",\r\n fill: {\r\n linearGradient: verticalGradient,\r\n stops: [[0, \"#FFF\"], [1, \"#ACF\"]]\r\n }\r\n },\r\n hoverState\r\n );\r\n hoverStyle = hoverState[STYLE];\r\n delete hoverState[STYLE];\r\n\r\n // Pressed state\r\n pressedState = merge(\r\n normalState,\r\n {\r\n stroke: \"#68A\",\r\n fill: {\r\n linearGradient: verticalGradient,\r\n stops: [[0, \"#9BD\"], [1, \"#CDF\"]]\r\n }\r\n },\r\n pressedState\r\n );\r\n pressedStyle = pressedState[STYLE];\r\n delete pressedState[STYLE];\r\n\r\n // Disabled state\r\n disabledState = merge(\r\n normalState,\r\n {\r\n style: {\r\n color: \"#CCC\"\r\n }\r\n },\r\n disabledState\r\n );\r\n disabledStyle = disabledState[STYLE];\r\n delete disabledState[STYLE];\r\n\r\n // Add the events. IE9 and IE10 need mouseover and mouseout to funciton (#667).\r\n addEvent(label.element, isIE ? \"mouseover\" : \"mouseenter\", function() {\r\n if (curState !== 3) {\r\n label.attr(hoverState).css(hoverStyle);\r\n }\r\n });\r\n addEvent(label.element, isIE ? \"mouseout\" : \"mouseleave\", function() {\r\n if (curState !== 3) {\r\n stateOptions = [normalState, hoverState, pressedState][curState];\r\n stateStyle = [normalStyle, hoverStyle, pressedStyle][curState];\r\n label.attr(stateOptions).css(stateStyle);\r\n }\r\n });\r\n\r\n label.setState = function(state) {\r\n label.state = curState = state;\r\n if (!state) {\r\n label.attr(normalState).css(normalStyle);\r\n }\r\n else if (state === 2) {\r\n label.attr(pressedState).css(pressedStyle);\r\n }\r\n else if (state === 3) {\r\n label.attr(disabledState).css(disabledStyle);\r\n }\r\n };\r\n\r\n return label\r\n .on(\"click\", function() {\r\n if (curState !== 3) {\r\n callback.call(label);\r\n }\r\n })\r\n .attr(normalState)\r\n .css(extend({ cursor: \"default\" }, normalStyle));\r\n },\r\n\r\n /**\r\n * Make a straight line crisper by not spilling out to neighbour pixels\r\n * @param {Array} points\r\n * @param {Number} width\r\n */\r\n crispLine: function(points, width) {\r\n // points format: [M, 0, 0, L, 100, 0]\r\n // normalize to a crisp line\r\n if (points[1] === points[4]) {\r\n // Substract due to #1129. Now bottom and left axis gridlines behave the same.\r\n points[1] = points[4] = mathRound(points[1]) - (width % 2) / 2;\r\n }\r\n if (points[2] === points[5]) {\r\n points[2] = points[5] = mathRound(points[2]) + (width % 2) / 2;\r\n }\r\n return points;\r\n },\r\n\r\n /**\r\n * Draw a path\r\n * @param {Array} path An SVG path in array form\r\n */\r\n path: function(path) {\r\n var attr = {\r\n fill: NONE\r\n };\r\n if (isArray(path)) {\r\n attr.d = path;\r\n }\r\n else if (isObject(path)) {\r\n // attributes\r\n extend(attr, path);\r\n }\r\n return this.createElement(\"path\").attr(attr);\r\n },\r\n\r\n /**\r\n * Draw and return an SVG circle\r\n * @param {Number} x The x position\r\n * @param {Number} y The y position\r\n * @param {Number} r The radius\r\n */\r\n circle: function(x, y, r) {\r\n var attr = isObject(x)\r\n ? x\r\n : {\r\n x: x,\r\n y: y,\r\n r: r\r\n };\r\n\r\n return this.createElement(\"circle\").attr(attr);\r\n },\r\n\r\n /**\r\n * Draw and return an arc\r\n * @param {Number} x X position\r\n * @param {Number} y Y position\r\n * @param {Number} r Radius\r\n * @param {Number} innerR Inner radius like used in donut charts\r\n * @param {Number} start Starting angle\r\n * @param {Number} end Ending angle\r\n */\r\n arc: function(x, y, r, innerR, start, end) {\r\n var arc;\r\n\r\n if (isObject(x)) {\r\n y = x.y;\r\n r = x.r;\r\n innerR = x.innerR;\r\n start = x.start;\r\n end = x.end;\r\n x = x.x;\r\n }\r\n\r\n // Arcs are defined as symbols for the ability to set\r\n // attributes in attr and animate\r\n arc = this.symbol(\"arc\", x || 0, y || 0, r || 0, r || 0, {\r\n innerR: innerR || 0,\r\n start: start || 0,\r\n end: end || 0\r\n });\r\n arc.r = r; // #959\r\n return arc;\r\n },\r\n\r\n /**\r\n * Draw and return a rectangle\r\n * @param {Number} x Left position\r\n * @param {Number} y Top position\r\n * @param {Number} width\r\n * @param {Number} height\r\n * @param {Number} r Border corner radius\r\n * @param {Number} strokeWidth A stroke width can be supplied to allow crisp drawing\r\n */\r\n rect: function(x, y, width, height, r, strokeWidth) {\r\n r = isObject(x) ? x.r : r;\r\n\r\n var wrapper = this.createElement(\"rect\").attr({\r\n rx: r,\r\n ry: r,\r\n fill: NONE\r\n });\r\n return wrapper.attr(\r\n isObject(x)\r\n ? x\r\n : // do not crispify when an object is passed in (as in column charts)\r\n wrapper.crisp(\r\n strokeWidth,\r\n x,\r\n y,\r\n mathMax(width, 0),\r\n mathMax(height, 0)\r\n )\r\n );\r\n },\r\n\r\n /**\r\n * Resize the box and re-align all aligned elements\r\n * @param {Object} width\r\n * @param {Object} height\r\n * @param {Boolean} animate\r\n *\r\n */\r\n setSize: function(width, height, animate) {\r\n var renderer = this,\r\n alignedObjects = renderer.alignedObjects,\r\n i = alignedObjects.length;\r\n\r\n renderer.width = width;\r\n renderer.height = height;\r\n\r\n renderer.boxWrapper[pick(animate, true) ? \"animate\" : \"attr\"]({\r\n width: width,\r\n height: height\r\n });\r\n\r\n while (i--) {\r\n alignedObjects[i].align();\r\n }\r\n },\r\n\r\n /**\r\n * Create a group\r\n * @param {String} name The group will be given a class name of 'highcharts-{name}'.\r\n * This can be used for styling and scripting.\r\n */\r\n g: function(name) {\r\n var elem = this.createElement(\"g\");\r\n return defined(name) ? elem.attr({ class: PREFIX + name }) : elem;\r\n },\r\n\r\n /**\r\n * Display an image\r\n * @param {String} src\r\n * @param {Number} x\r\n * @param {Number} y\r\n * @param {Number} width\r\n * @param {Number} height\r\n */\r\n image: function(src, x, y, width, height) {\r\n var attribs = {\r\n preserveAspectRatio: NONE\r\n },\r\n elemWrapper;\r\n\r\n // optional properties\r\n if (arguments.length > 1) {\r\n extend(attribs, {\r\n x: x,\r\n y: y,\r\n width: width,\r\n height: height\r\n });\r\n }\r\n\r\n elemWrapper = this.createElement(\"image\").attr(attribs);\r\n\r\n // set the href in the xlink namespace\r\n if (elemWrapper.element.setAttributeNS) {\r\n elemWrapper.element.setAttributeNS(\r\n \"http://www.w3.org/1999/xlink\",\r\n \"href\",\r\n src\r\n );\r\n }\r\n else {\r\n // could be exporting in IE\r\n // using href throws \"not supported\" in ie7 and under, requries regex shim to fix later\r\n elemWrapper.element.setAttribute(\"hc-svg-href\", src);\r\n }\r\n\r\n return elemWrapper;\r\n },\r\n\r\n /**\r\n * Draw a symbol out of pre-defined shape paths from the namespace 'symbol' object.\r\n *\r\n * @param {Object} symbol\r\n * @param {Object} x\r\n * @param {Object} y\r\n * @param {Object} radius\r\n * @param {Object} options\r\n */\r\n symbol: function(symbol, x, y, width, height, options) {\r\n var obj,\r\n // get the symbol definition function\r\n symbolFn = this.symbols[symbol],\r\n // check if there's a path defined for this symbol\r\n path =\r\n symbolFn &&\r\n symbolFn(mathRound(x), mathRound(y), width, height, options),\r\n imageElement,\r\n imageRegex = /^url\\((.*?)\\)$/,\r\n imageSrc,\r\n imageSize,\r\n centerImage;\r\n\r\n if (path) {\r\n obj = this.path(path);\r\n // expando properties for use in animate and attr\r\n extend(obj, {\r\n symbolName: symbol,\r\n x: x,\r\n y: y,\r\n width: width,\r\n height: height\r\n });\r\n if (options) {\r\n extend(obj, options);\r\n }\r\n\r\n // image symbols\r\n }\r\n else if (imageRegex.test(symbol)) {\r\n // On image load, set the size and position\r\n centerImage = function(img, size) {\r\n if (img.element) {\r\n // it may be destroyed in the meantime (#1390)\r\n img.attr({\r\n width: size[0],\r\n height: size[1]\r\n });\r\n\r\n if (!img.alignByTranslate) {\r\n // #185\r\n img.translate(\r\n mathRound((width - size[0]) / 2), // #1378\r\n mathRound((height - size[1]) / 2)\r\n );\r\n }\r\n }\r\n };\r\n\r\n imageSrc = symbol.match(imageRegex)[1];\r\n imageSize = symbolSizes[imageSrc];\r\n\r\n // Ireate the image synchronously, add attribs async\r\n obj = this.image(imageSrc).attr({\r\n x: x,\r\n y: y\r\n });\r\n obj.isImg = true;\r\n\r\n if (imageSize) {\r\n centerImage(obj, imageSize);\r\n }\r\n else {\r\n // Initialize image to be 0 size so export will still function if there's no cached sizes.\r\n //\r\n obj.attr({ width: 0, height: 0 });\r\n\r\n // Create a dummy JavaScript image to get the width and height. Due to a bug in IE < 8,\r\n // the created element must be assigned to a variable in order to load (#292).\r\n imageElement = createElement(\"img\", {\r\n onload: function() {\r\n centerImage(\r\n obj,\r\n (symbolSizes[imageSrc] = [this.width, this.height])\r\n );\r\n },\r\n src: imageSrc\r\n });\r\n }\r\n }\r\n\r\n return obj;\r\n },\r\n\r\n /**\r\n * An extendable collection of functions for defining symbol paths.\r\n */\r\n symbols: {\r\n circle: function(x, y, w, h) {\r\n var cpw = 0.166 * w;\r\n return [\r\n M,\r\n x + w / 2,\r\n y,\r\n \"C\",\r\n x + w + cpw,\r\n y,\r\n x + w + cpw,\r\n y + h,\r\n x + w / 2,\r\n y + h,\r\n \"C\",\r\n x - cpw,\r\n y + h,\r\n x - cpw,\r\n y,\r\n x + w / 2,\r\n y,\r\n \"Z\"\r\n ];\r\n },\r\n\r\n square: function(x, y, w, h) {\r\n return [M, x, y, L, x + w, y, x + w, y + h, x, y + h, \"Z\"];\r\n },\r\n\r\n triangle: function(x, y, w, h) {\r\n return [M, x + w / 2, y, L, x + w, y + h, x, y + h, \"Z\"];\r\n },\r\n\r\n \"triangle-down\": function(x, y, w, h) {\r\n return [M, x, y, L, x + w, y, x + w / 2, y + h, \"Z\"];\r\n },\r\n diamond: function(x, y, w, h) {\r\n return [\r\n M,\r\n x + w / 2,\r\n y,\r\n L,\r\n x + w,\r\n y + h / 2,\r\n x + w / 2,\r\n y + h,\r\n x,\r\n y + h / 2,\r\n \"Z\"\r\n ];\r\n },\r\n arc: function(x, y, w, h, options) {\r\n var start = options.start,\r\n radius = options.r || w || h,\r\n end = options.end - 0.001, // to prevent cos and sin of start and end from becoming equal on 360 arcs (related: #1561)\r\n innerRadius = options.innerR,\r\n open = options.open,\r\n cosStart = mathCos(start),\r\n sinStart = mathSin(start),\r\n cosEnd = mathCos(end),\r\n sinEnd = mathSin(end),\r\n longArc = options.end - start < mathPI ? 0 : 1;\r\n\r\n return [\r\n M,\r\n x + radius * cosStart,\r\n y + radius * sinStart,\r\n \"A\", // arcTo\r\n radius, // x radius\r\n radius, // y radius\r\n 0, // slanting\r\n longArc, // long or short arc\r\n 1, // clockwise\r\n x + radius * cosEnd,\r\n y + radius * sinEnd,\r\n open ? M : L,\r\n x + innerRadius * cosEnd,\r\n y + innerRadius * sinEnd,\r\n \"A\", // arcTo\r\n innerRadius, // x radius\r\n innerRadius, // y radius\r\n 0, // slanting\r\n longArc, // long or short arc\r\n 0, // clockwise\r\n x + innerRadius * cosStart,\r\n y + innerRadius * sinStart,\r\n\r\n open ? \"\" : \"Z\" // close\r\n ];\r\n }\r\n },\r\n\r\n /**\r\n * Define a clipping rectangle\r\n * @param {String} id\r\n * @param {Number} x\r\n * @param {Number} y\r\n * @param {Number} width\r\n * @param {Number} height\r\n */\r\n clipRect: function(x, y, width, height) {\r\n var wrapper,\r\n id = PREFIX + idCounter++,\r\n clipPath = this.createElement(\"clipPath\")\r\n .attr({\r\n id: id\r\n })\r\n .add(this.defs);\r\n\r\n wrapper = this.rect(x, y, width, height, 0).add(clipPath);\r\n wrapper.id = id;\r\n wrapper.clipPath = clipPath;\r\n\r\n return wrapper;\r\n },\r\n\r\n /**\r\n * Take a color and return it if it's a string, make it a gradient if it's a\r\n * gradient configuration object. Prior to Highstock, an array was used to define\r\n * a linear gradient with pixel positions relative to the SVG. In newer versions\r\n * we change the coordinates to apply relative to the shape, using coordinates\r\n * 0-1 within the shape. To preserve backwards compatibility, linearGradient\r\n * in this definition is an object of x1, y1, x2 and y2.\r\n *\r\n * @param {Object} color The color or config object\r\n */\r\n color: function(color, elem, prop) {\r\n var renderer = this,\r\n colorObject,\r\n regexRgba = /^rgba/,\r\n gradName,\r\n gradAttr,\r\n gradients,\r\n gradientObject,\r\n stops,\r\n stopColor,\r\n stopOpacity,\r\n radialReference,\r\n n,\r\n id,\r\n key = [];\r\n\r\n // Apply linear or radial gradients\r\n if (color && color.linearGradient) {\r\n gradName = \"linearGradient\";\r\n }\r\n else if (color && color.radialGradient) {\r\n gradName = \"radialGradient\";\r\n }\r\n\r\n if (gradName) {\r\n gradAttr = color[gradName];\r\n gradients = renderer.gradients;\r\n stops = color.stops;\r\n radialReference = elem.radialReference;\r\n\r\n // Keep < 2.2 kompatibility\r\n if (isArray(gradAttr)) {\r\n color[gradName] = gradAttr = {\r\n x1: gradAttr[0],\r\n y1: gradAttr[1],\r\n x2: gradAttr[2],\r\n y2: gradAttr[3],\r\n gradientUnits: \"userSpaceOnUse\"\r\n };\r\n }\r\n\r\n // Correct the radial gradient for the radial reference system\r\n if (\r\n gradName === \"radialGradient\" &&\r\n radialReference &&\r\n !defined(gradAttr.gradientUnits)\r\n ) {\r\n gradAttr = merge(gradAttr, {\r\n cx:\r\n radialReference[0] -\r\n radialReference[2] / 2 +\r\n gradAttr.cx * radialReference[2],\r\n cy:\r\n radialReference[1] -\r\n radialReference[2] / 2 +\r\n gradAttr.cy * radialReference[2],\r\n r: gradAttr.r * radialReference[2],\r\n gradientUnits: \"userSpaceOnUse\"\r\n });\r\n }\r\n\r\n // Build the unique key to detect whether we need to create a new element (#1282)\r\n for (n in gradAttr) {\r\n if (n !== \"id\") {\r\n key.push(n, gradAttr[n]);\r\n }\r\n }\r\n for (n in stops) {\r\n key.push(stops[n]);\r\n }\r\n key = key.join(\",\");\r\n\r\n // Check if a gradient object with the same config object is created within this renderer\r\n if (gradients[key]) {\r\n id = gradients[key].id;\r\n }\r\n else {\r\n // Set the id and create the element\r\n gradAttr.id = id = PREFIX + idCounter++;\r\n gradients[key] = gradientObject = renderer\r\n .createElement(gradName)\r\n .attr(gradAttr)\r\n .add(renderer.defs);\r\n\r\n // The gradient needs to keep a list of stops to be able to destroy them\r\n gradientObject.stops = [];\r\n each(stops, function(stop) {\r\n var stopObject;\r\n if (regexRgba.test(stop[1])) {\r\n colorObject = Color(stop[1]);\r\n stopColor = colorObject.get(\"rgb\");\r\n stopOpacity = colorObject.get(\"a\");\r\n }\r\n else {\r\n stopColor = stop[1];\r\n stopOpacity = 1;\r\n }\r\n stopObject = renderer\r\n .createElement(\"stop\")\r\n .attr({\r\n offset: stop[0],\r\n \"stop-color\": stopColor,\r\n \"stop-opacity\": stopOpacity\r\n })\r\n .add(gradientObject);\r\n\r\n // Add the stop element to the gradient\r\n gradientObject.stops.push(stopObject);\r\n });\r\n }\r\n\r\n // Return the reference to the gradient object\r\n return \"url(\" + renderer.url + \"#\" + id + \")\";\r\n\r\n // Webkit and Batik can't show rgba.\r\n }\r\n else if (regexRgba.test(color)) {\r\n colorObject = Color(color);\r\n attr(elem, prop + \"-opacity\", colorObject.get(\"a\"));\r\n\r\n return colorObject.get(\"rgb\");\r\n }\r\n else {\r\n // Remove the opacity attribute added above. Does not throw if the attribute is not there.\r\n elem.removeAttribute(prop + \"-opacity\");\r\n\r\n return color;\r\n }\r\n },\r\n\r\n /**\r\n * Add text to the SVG object\r\n * @param {String} str\r\n * @param {Number} x Left position\r\n * @param {Number} y Top position\r\n * @param {Boolean} useHTML Use HTML to render the text\r\n */\r\n text: function(str, x, y, useHTML) {\r\n // declare variables\r\n var renderer = this,\r\n defaultChartStyle = defaultOptions.chart.style,\r\n fakeSVG = useCanVG || (!hasSVG && renderer.forExport),\r\n wrapper;\r\n\r\n if (useHTML && !renderer.forExport) {\r\n return renderer.html(str, x, y);\r\n }\r\n\r\n x = mathRound(pick(x, 0));\r\n y = mathRound(pick(y, 0));\r\n\r\n wrapper = renderer\r\n .createElement(\"text\")\r\n .attr({\r\n x: x,\r\n y: y,\r\n text: str\r\n })\r\n .css({\r\n fontFamily: defaultChartStyle.fontFamily,\r\n fontSize: defaultChartStyle.fontSize\r\n });\r\n\r\n // Prevent wrapping from creating false offsetWidths in export in legacy IE (#1079, #1063)\r\n if (fakeSVG) {\r\n wrapper.css({\r\n position: ABSOLUTE\r\n });\r\n }\r\n\r\n wrapper.x = x;\r\n wrapper.y = y;\r\n return wrapper;\r\n },\r\n\r\n /**\r\n * Create HTML text node. This is used by the VML renderer as well as the SVG\r\n * renderer through the useHTML option.\r\n *\r\n * @param {String} str\r\n * @param {Number} x\r\n * @param {Number} y\r\n */\r\n html: function(str, x, y) {\r\n var defaultChartStyle = defaultOptions.chart.style,\r\n wrapper = this.createElement(\"span\"),\r\n attrSetters = wrapper.attrSetters,\r\n element = wrapper.element,\r\n renderer = wrapper.renderer;\r\n\r\n // Text setter\r\n attrSetters.text = function(value) {\r\n if (value !== element.innerHTML) {\r\n delete this.bBox;\r\n }\r\n element.innerHTML = value;\r\n return false;\r\n };\r\n\r\n // Various setters which rely on update transform\r\n attrSetters.x = attrSetters.y = attrSetters.align = function(value, key) {\r\n if (key === \"align\") {\r\n key = \"textAlign\"; // Do not overwrite the SVGElement.align method. Same as VML.\r\n }\r\n wrapper[key] = value;\r\n wrapper.htmlUpdateTransform();\r\n return false;\r\n };\r\n\r\n // Set the default attributes\r\n wrapper\r\n .attr({\r\n text: str,\r\n x: mathRound(x),\r\n y: mathRound(y)\r\n })\r\n .css({\r\n position: ABSOLUTE,\r\n whiteSpace: \"nowrap\",\r\n fontFamily: defaultChartStyle.fontFamily,\r\n fontSize: defaultChartStyle.fontSize\r\n });\r\n\r\n // Use the HTML specific .css method\r\n wrapper.css = wrapper.htmlCss;\r\n\r\n // This is specific for HTML within SVG\r\n if (renderer.isSVG) {\r\n wrapper.add = function(svgGroupWrapper) {\r\n var htmlGroup,\r\n container = renderer.box.parentNode,\r\n parentGroup,\r\n parents = [];\r\n\r\n this.parentGroup = svgGroupWrapper;\r\n\r\n // Create a mock group to hold the HTML elements\r\n if (svgGroupWrapper) {\r\n htmlGroup = svgGroupWrapper.div;\r\n if (!htmlGroup) {\r\n // Read the parent chain into an array and read from top down\r\n parentGroup = svgGroupWrapper;\r\n while (parentGroup) {\r\n parents.push(parentGroup);\r\n\r\n // Move up to the next parent group\r\n parentGroup = parentGroup.parentGroup;\r\n }\r\n\r\n // Ensure dynamically updating position when any parent is translated\r\n each(parents.reverse(), function(parentGroup) {\r\n var htmlGroupStyle;\r\n\r\n // Create a HTML div and append it to the parent div to emulate\r\n // the SVG group structure\r\n htmlGroup = parentGroup.div =\r\n parentGroup.div ||\r\n createElement(\r\n DIV,\r\n {\r\n className: attr(parentGroup.element, \"class\")\r\n },\r\n {\r\n position: ABSOLUTE,\r\n left: (parentGroup.translateX || 0) + PX,\r\n top: (parentGroup.translateY || 0) + PX\r\n },\r\n htmlGroup || container\r\n ); // the top group is appended to container\r\n\r\n // Shortcut\r\n htmlGroupStyle = htmlGroup.style;\r\n\r\n // Set listeners to update the HTML div's position whenever the SVG group\r\n // position is changed\r\n extend(parentGroup.attrSetters, {\r\n translateX: function(value) {\r\n htmlGroupStyle.left = value + PX;\r\n },\r\n translateY: function(value) {\r\n htmlGroupStyle.top = value + PX;\r\n },\r\n visibility: function(value, key) {\r\n htmlGroupStyle[key] = value;\r\n }\r\n });\r\n });\r\n }\r\n }\r\n else {\r\n htmlGroup = container;\r\n }\r\n\r\n htmlGroup.appendChild(element);\r\n\r\n // Shared with VML:\r\n wrapper.added = true;\r\n if (wrapper.alignOnAdd) {\r\n wrapper.htmlUpdateTransform();\r\n }\r\n\r\n return wrapper;\r\n };\r\n }\r\n return wrapper;\r\n },\r\n\r\n /**\r\n * Utility to return the baseline offset and total line height from the font size\r\n */\r\n fontMetrics: function(fontSize) {\r\n fontSize = pInt(fontSize || 11);\r\n\r\n // Empirical values found by comparing font size and bounding box height.\r\n // Applies to the default font family. http://jsfiddle.net/highcharts/7xvn7/\r\n var lineHeight = fontSize < 24 ? fontSize + 4 : mathRound(fontSize * 1.2),\r\n baseline = mathRound(lineHeight * 0.8);\r\n\r\n return {\r\n h: lineHeight,\r\n b: baseline\r\n };\r\n },\r\n\r\n /**\r\n * Add a label, a text item that can hold a colored or gradient background\r\n * as well as a border and shadow.\r\n * @param {string} str\r\n * @param {Number} x\r\n * @param {Number} y\r\n * @param {String} shape\r\n * @param {Number} anchorX In case the shape has a pointer, like a flag, this is the\r\n * coordinates it should be pinned to\r\n * @param {Number} anchorY\r\n * @param {Boolean} baseline Whether to position the label relative to the text baseline,\r\n * like renderer.text, or to the upper border of the rectangle.\r\n * @param {String} className Class name for the group\r\n */\r\n label: function(\r\n str,\r\n x,\r\n y,\r\n shape,\r\n anchorX,\r\n anchorY,\r\n useHTML,\r\n baseline,\r\n className\r\n ) {\r\n var renderer = this,\r\n wrapper = renderer.g(className),\r\n text = renderer.text(\"\", 0, 0, useHTML).attr({\r\n zIndex: 1\r\n }),\r\n //.add(wrapper),\r\n box,\r\n bBox,\r\n alignFactor = 0,\r\n padding = 3,\r\n paddingLeft = 0,\r\n width,\r\n height,\r\n wrapperX,\r\n wrapperY,\r\n crispAdjust = 0,\r\n deferredAttr = {},\r\n baselineOffset,\r\n attrSetters = wrapper.attrSetters,\r\n needsBox;\r\n\r\n /**\r\n * This function runs after the label is added to the DOM (when the bounding box is\r\n * available), and after the text of the label is updated to detect the new bounding\r\n * box and reflect it in the border box.\r\n */\r\n function updateBoxSize() {\r\n var boxX,\r\n boxY,\r\n style = text.element.style;\r\n\r\n bBox =\r\n (width === undefined ||\r\n height === undefined ||\r\n wrapper.styles.textAlign) &&\r\n text.getBBox();\r\n wrapper.width = (width || bBox.width || 0) + 2 * padding + paddingLeft;\r\n wrapper.height = (height || bBox.height || 0) + 2 * padding;\r\n\r\n // update the label-scoped y offset\r\n baselineOffset =\r\n padding + renderer.fontMetrics(style && style.fontSize).b;\r\n\r\n if (needsBox) {\r\n // create the border box if it is not already present\r\n if (!box) {\r\n boxX = mathRound(-alignFactor * padding);\r\n boxY = baseline ? -baselineOffset : 0;\r\n\r\n wrapper.box = box = shape\r\n ? renderer.symbol(\r\n shape,\r\n boxX,\r\n boxY,\r\n wrapper.width,\r\n wrapper.height,\r\n deferredAttr\r\n )\r\n : renderer.rect(\r\n boxX,\r\n boxY,\r\n wrapper.width,\r\n wrapper.height,\r\n 0,\r\n deferredAttr[STROKE_WIDTH]\r\n );\r\n box.add(wrapper);\r\n }\r\n\r\n // apply the box attributes\r\n if (!box.isImg) {\r\n // #1630\r\n box.attr(\r\n merge(\r\n {\r\n width: wrapper.width,\r\n height: wrapper.height\r\n },\r\n deferredAttr\r\n )\r\n );\r\n }\r\n deferredAttr = null;\r\n }\r\n }\r\n\r\n /**\r\n * This function runs after setting text or padding, but only if padding is changed\r\n */\r\n function updateTextPadding() {\r\n var styles = wrapper.styles,\r\n textAlign = styles && styles.textAlign,\r\n x = paddingLeft + padding * (1 - alignFactor),\r\n y;\r\n\r\n // determin y based on the baseline\r\n y = baseline ? 0 : baselineOffset;\r\n\r\n // compensate for alignment\r\n if (\r\n defined(width) &&\r\n (textAlign === \"center\" || textAlign === \"right\")\r\n ) {\r\n x += { center: 0.5, right: 1 }[textAlign] * (width - bBox.width);\r\n }\r\n\r\n // update if anything changed\r\n if (x !== text.x || y !== text.y) {\r\n text.attr({\r\n x: x,\r\n y: y\r\n });\r\n }\r\n\r\n // record current values\r\n text.x = x;\r\n text.y = y;\r\n }\r\n\r\n /**\r\n * Set a box attribute, or defer it if the box is not yet created\r\n * @param {Object} key\r\n * @param {Object} value\r\n */\r\n function boxAttr(key, value) {\r\n if (box) {\r\n box.attr(key, value);\r\n }\r\n else {\r\n deferredAttr[key] = value;\r\n }\r\n }\r\n\r\n function getSizeAfterAdd() {\r\n text.add(wrapper);\r\n wrapper.attr({\r\n text: str, // alignment is available now\r\n x: x,\r\n y: y\r\n });\r\n\r\n if (box && defined(anchorX)) {\r\n wrapper.attr({\r\n anchorX: anchorX,\r\n anchorY: anchorY\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * After the text element is added, get the desired size of the border box\r\n * and add it before the text in the DOM.\r\n */\r\n addEvent(wrapper, \"add\", getSizeAfterAdd);\r\n\r\n /*\r\n * Add specific attribute setters.\r\n */\r\n\r\n // only change local variables\r\n attrSetters.width = function(value) {\r\n width = value;\r\n return false;\r\n };\r\n attrSetters.height = function(value) {\r\n height = value;\r\n return false;\r\n };\r\n attrSetters.padding = function(value) {\r\n if (defined(value) && value !== padding) {\r\n padding = value;\r\n updateTextPadding();\r\n }\r\n return false;\r\n };\r\n attrSetters.paddingLeft = function(value) {\r\n if (defined(value) && value !== paddingLeft) {\r\n paddingLeft = value;\r\n updateTextPadding();\r\n }\r\n return false;\r\n };\r\n\r\n // change local variable and set attribue as well\r\n attrSetters.align = function(value) {\r\n alignFactor = { left: 0, center: 0.5, right: 1 }[value];\r\n return false; // prevent setting text-anchor on the group\r\n };\r\n\r\n // apply these to the box and the text alike\r\n attrSetters.text = function(value, key) {\r\n text.attr(key, value);\r\n updateBoxSize();\r\n updateTextPadding();\r\n return false;\r\n };\r\n\r\n // apply these to the box but not to the text\r\n attrSetters[STROKE_WIDTH] = function(value, key) {\r\n needsBox = true;\r\n crispAdjust = (value % 2) / 2;\r\n boxAttr(key, value);\r\n return false;\r\n };\r\n attrSetters.stroke = attrSetters.fill = attrSetters.r = function(\r\n value,\r\n key\r\n ) {\r\n if (key === \"fill\") {\r\n needsBox = true;\r\n }\r\n boxAttr(key, value);\r\n return false;\r\n };\r\n attrSetters.anchorX = function(value, key) {\r\n anchorX = value;\r\n boxAttr(key, value + crispAdjust - wrapperX);\r\n return false;\r\n };\r\n attrSetters.anchorY = function(value, key) {\r\n anchorY = value;\r\n boxAttr(key, value - wrapperY);\r\n return false;\r\n };\r\n\r\n // rename attributes\r\n attrSetters.x = function(value) {\r\n wrapper.x = value; // for animation getter\r\n value -= alignFactor * ((width || bBox.width) + padding);\r\n wrapperX = mathRound(value);\r\n\r\n wrapper.attr(\"translateX\", wrapperX);\r\n return false;\r\n };\r\n attrSetters.y = function(value) {\r\n wrapperY = wrapper.y = mathRound(value);\r\n wrapper.attr(\"translateY\", wrapperY);\r\n return false;\r\n };\r\n\r\n // Redirect certain methods to either the box or the text\r\n var baseCss = wrapper.css;\r\n return extend(wrapper, {\r\n /**\r\n * Pick up some properties and apply them to the text instead of the wrapper\r\n */\r\n css: function(styles) {\r\n if (styles) {\r\n var textStyles = {};\r\n styles = merge(styles); // create a copy to avoid altering the original object (#537)\r\n each(\r\n [\r\n \"fontSize\",\r\n \"fontWeight\",\r\n \"fontFamily\",\r\n \"color\",\r\n \"lineHeight\",\r\n \"width\",\r\n \"textDecoration\",\r\n \"textShadow\"\r\n ],\r\n function(prop) {\r\n if (styles[prop] !== UNDEFINED) {\r\n textStyles[prop] = styles[prop];\r\n delete styles[prop];\r\n }\r\n }\r\n );\r\n text.css(textStyles);\r\n }\r\n return baseCss.call(wrapper, styles);\r\n },\r\n /**\r\n * Return the bounding box of the box, not the group\r\n */\r\n getBBox: function() {\r\n return {\r\n width: bBox.width + 2 * padding,\r\n height: bBox.height + 2 * padding,\r\n x: bBox.x - padding,\r\n y: bBox.y - padding\r\n };\r\n },\r\n /**\r\n * Apply the shadow to the box\r\n */\r\n shadow: function(b) {\r\n if (box) {\r\n box.shadow(b);\r\n }\r\n return wrapper;\r\n },\r\n /**\r\n * Destroy and release memory.\r\n */\r\n destroy: function() {\r\n removeEvent(wrapper, \"add\", getSizeAfterAdd);\r\n\r\n // Added by button implementation\r\n removeEvent(wrapper.element, \"mouseenter\");\r\n removeEvent(wrapper.element, \"mouseleave\");\r\n\r\n if (text) {\r\n text = text.destroy();\r\n }\r\n if (box) {\r\n box = box.destroy();\r\n }\r\n // Call base implementation to destroy the rest\r\n SVGElement.prototype.destroy.call(wrapper);\r\n\r\n // Release local pointers (#1298)\r\n wrapper = renderer = updateBoxSize = updateTextPadding = boxAttr = getSizeAfterAdd = null;\r\n }\r\n });\r\n }\r\n }; // end SVGRenderer\r\n\r\n // general renderer\r\n Renderer = SVGRenderer;\r\n\r\n /* ****************************************************************************\r\n * *\r\n * START OF INTERNET EXPLORER <= 8 SPECIFIC CODE *\r\n * *\r\n * For applications and websites that don't need IE support, like platform *\r\n * targeted mobile apps and web apps, this code can be removed. *\r\n * *\r\n *****************************************************************************/\r\n\r\n /**\r\n * @constructor\r\n */\r\n var VMLRenderer, VMLElement;\r\n if (!hasSVG && !useCanVG) {\r\n /**\r\n * The VML element wrapper.\r\n */\r\n Highcharts.VMLElement = VMLElement = {\r\n /**\r\n * Initialize a new VML element wrapper. It builds the markup as a string\r\n * to minimize DOM traffic.\r\n * @param {Object} renderer\r\n * @param {Object} nodeName\r\n */\r\n init: function(renderer, nodeName) {\r\n var wrapper = this,\r\n markup = [\"<\", nodeName, ' filled=\"f\" stroked=\"f\"'],\r\n style = [\"position: \", ABSOLUTE, \";\"],\r\n isDiv = nodeName === DIV;\r\n\r\n // divs and shapes need size\r\n if (nodeName === \"shape\" || isDiv) {\r\n style.push(\"left:0;top:0;width:1px;height:1px;\");\r\n }\r\n style.push(\"visibility: \", isDiv ? HIDDEN : VISIBLE);\r\n\r\n markup.push(' style=\"', style.join(\"\"), '\"/>');\r\n\r\n // create element with default attributes and style\r\n if (nodeName) {\r\n markup =\r\n isDiv || nodeName === \"span\" || nodeName === \"img\"\r\n ? markup.join(\"\")\r\n : renderer.prepVML(markup);\r\n wrapper.element = createElement(markup);\r\n }\r\n\r\n wrapper.renderer = renderer;\r\n wrapper.attrSetters = {};\r\n },\r\n\r\n /**\r\n * Add the node to the given parent\r\n * @param {Object} parent\r\n */\r\n add: function(parent) {\r\n var wrapper = this,\r\n renderer = wrapper.renderer,\r\n element = wrapper.element,\r\n box = renderer.box,\r\n inverted = parent && parent.inverted,\r\n // get the parent node\r\n parentNode = parent ? parent.element || parent : box;\r\n\r\n // if the parent group is inverted, apply inversion on all children\r\n if (inverted) {\r\n // only on groups\r\n renderer.invertChild(element, parentNode);\r\n }\r\n\r\n // append it\r\n parentNode.appendChild(element);\r\n\r\n // align text after adding to be able to read offset\r\n wrapper.added = true;\r\n if (wrapper.alignOnAdd && !wrapper.deferUpdateTransform) {\r\n wrapper.updateTransform();\r\n }\r\n\r\n // fire an event for internal hooks\r\n fireEvent(wrapper, \"add\");\r\n\r\n return wrapper;\r\n },\r\n\r\n /**\r\n * VML always uses htmlUpdateTransform\r\n */\r\n updateTransform: SVGElement.prototype.htmlUpdateTransform,\r\n\r\n /**\r\n * Set the rotation of a span with oldIE's filter\r\n */\r\n setSpanRotation: function(rotation, sintheta, costheta) {\r\n // Adjust for alignment and rotation. Rotation of useHTML content is not yet implemented\r\n // but it can probably be implemented for Firefox 3.5+ on user request. FF3.5+\r\n // has support for CSS3 transform. The getBBox method also needs to be updated\r\n // to compensate for the rotation, like it currently does for SVG.\r\n // Test case: http://highcharts.com/tests/?file=text-rotation\r\n css(this.element, {\r\n filter: rotation\r\n ? [\r\n \"progid:DXImageTransform.Microsoft.Matrix(M11=\",\r\n costheta,\r\n \", M12=\",\r\n -sintheta,\r\n \", M21=\",\r\n sintheta,\r\n \", M22=\",\r\n costheta,\r\n \", sizingMethod='auto expand')\"\r\n ].join(\"\")\r\n : NONE\r\n });\r\n },\r\n\r\n /**\r\n * Converts a subset of an SVG path definition to its VML counterpart. Takes an array\r\n * as the parameter and returns a string.\r\n */\r\n pathToVML: function(value) {\r\n // convert paths\r\n var i = value.length,\r\n path = [],\r\n clockwise;\r\n\r\n while (i--) {\r\n // Multiply by 10 to allow subpixel precision.\r\n // Substracting half a pixel seems to make the coordinates\r\n // align with SVG, but this hasn't been tested thoroughly\r\n if (isNumber(value[i])) {\r\n path[i] = mathRound(value[i] * 10) - 5;\r\n }\r\n else if (value[i] === \"Z\") {\r\n // close the path\r\n path[i] = \"x\";\r\n }\r\n else {\r\n path[i] = value[i];\r\n\r\n // When the start X and end X coordinates of an arc are too close,\r\n // they are rounded to the same value above. In this case, substract 1 from the end X\r\n // position. #760, #1371.\r\n if (value.isArc && (value[i] === \"wa\" || value[i] === \"at\")) {\r\n clockwise = value[i] === \"wa\" ? 1 : -1; // #1642\r\n if (path[i + 5] === path[i + 7]) {\r\n path[i + 7] -= clockwise;\r\n }\r\n // Start and end Y (#1410)\r\n if (path[i + 6] === path[i + 8]) {\r\n path[i + 8] -= clockwise;\r\n }\r\n }\r\n }\r\n }\r\n // Loop up again to handle path shortcuts (#2132)\r\n /*while (i++ < path.length) {\r\n\t\t\tif (path[i] === 'H') { // horizontal line to\r\n\t\t\t\tpath[i] = 'L';\r\n\t\t\t\tpath.splice(i + 2, 0, path[i - 1]);\r\n\t\t\t} else if (path[i] === 'V') { // vertical line to\r\n\t\t\t\tpath[i] = 'L';\r\n\t\t\t\tpath.splice(i + 1, 0, path[i - 2]);\r\n\t\t\t}\r\n\t\t}*/\r\n return path.join(\" \") || \"x\";\r\n },\r\n\r\n /**\r\n * Get or set attributes\r\n */\r\n attr: function(hash, val) {\r\n var wrapper = this,\r\n key,\r\n value,\r\n i,\r\n result,\r\n element = wrapper.element || {},\r\n elemStyle = element.style,\r\n nodeName = element.nodeName,\r\n renderer = wrapper.renderer,\r\n symbolName = wrapper.symbolName,\r\n hasSetSymbolSize,\r\n shadows = wrapper.shadows,\r\n skipAttr,\r\n attrSetters = wrapper.attrSetters,\r\n ret = wrapper;\r\n\r\n // single key-value pair\r\n if (isString(hash) && defined(val)) {\r\n key = hash;\r\n hash = {};\r\n hash[key] = val;\r\n }\r\n\r\n // used as a getter, val is undefined\r\n if (isString(hash)) {\r\n key = hash;\r\n if (key === \"strokeWidth\" || key === \"stroke-width\") {\r\n ret = wrapper.strokeweight;\r\n }\r\n else {\r\n ret = wrapper[key];\r\n }\r\n\r\n // setter\r\n }\r\n else {\r\n for (key in hash) {\r\n value = hash[key];\r\n skipAttr = false;\r\n\r\n // check for a specific attribute setter\r\n result =\r\n attrSetters[key] && attrSetters[key].call(wrapper, value, key);\r\n\r\n if (result !== false && value !== null) {\r\n // #620\r\n\r\n if (result !== UNDEFINED) {\r\n value = result; // the attribute setter has returned a new value to set\r\n }\r\n\r\n // prepare paths\r\n // symbols\r\n if (\r\n symbolName &&\r\n /^(x|y|r|start|end|width|height|innerR|anchorX|anchorY)/.test(\r\n key\r\n )\r\n ) {\r\n // if one of the symbol size affecting parameters are changed,\r\n // check all the others only once for each call to an element's\r\n // .attr() method\r\n if (!hasSetSymbolSize) {\r\n wrapper.symbolAttr(hash);\r\n\r\n hasSetSymbolSize = true;\r\n }\r\n skipAttr = true;\r\n }\r\n else if (key === \"d\") {\r\n value = value || [];\r\n wrapper.d = value.join(\" \"); // used in getter for animation\r\n\r\n element.path = value = wrapper.pathToVML(value);\r\n\r\n // update shadows\r\n if (shadows) {\r\n i = shadows.length;\r\n while (i--) {\r\n shadows[i].path = shadows[i].cutOff\r\n ? this.cutOffPath(value, shadows[i].cutOff)\r\n : value;\r\n }\r\n }\r\n skipAttr = true;\r\n\r\n // handle visibility\r\n }\r\n else if (key === \"visibility\") {\r\n // let the shadow follow the main element\r\n if (shadows) {\r\n i = shadows.length;\r\n while (i--) {\r\n shadows[i].style[key] = value;\r\n }\r\n }\r\n\r\n // Instead of toggling the visibility CSS property, move the div out of the viewport.\r\n // This works around #61 and #586\r\n if (nodeName === \"DIV\") {\r\n value = value === HIDDEN ? \"-999em\" : 0;\r\n\r\n // In order to redraw, IE7 needs the div to be visible when tucked away\r\n // outside the viewport. So the visibility is actually opposite of\r\n // the expected value. This applies to the tooltip only.\r\n if (!docMode8) {\r\n elemStyle[key] = value ? VISIBLE : HIDDEN;\r\n }\r\n key = \"top\";\r\n }\r\n elemStyle[key] = value;\r\n skipAttr = true;\r\n\r\n // directly mapped to css\r\n }\r\n else if (key === \"zIndex\") {\r\n if (value) {\r\n elemStyle[key] = value;\r\n }\r\n skipAttr = true;\r\n\r\n // x, y, width, height\r\n }\r\n else if (inArray(key, [\"x\", \"y\", \"width\", \"height\"]) !== -1) {\r\n wrapper[key] = value; // used in getter\r\n\r\n if (key === \"x\" || key === \"y\") {\r\n key = { x: \"left\", y: \"top\" }[key];\r\n }\r\n else {\r\n value = mathMax(0, value); // don't set width or height below zero (#311)\r\n }\r\n\r\n // clipping rectangle special\r\n if (wrapper.updateClipping) {\r\n wrapper[key] = value; // the key is now 'left' or 'top' for 'x' and 'y'\r\n wrapper.updateClipping();\r\n }\r\n else {\r\n // normal\r\n elemStyle[key] = value;\r\n }\r\n\r\n skipAttr = true;\r\n\r\n // class name\r\n }\r\n else if (key === \"class\" && nodeName === \"DIV\") {\r\n // IE8 Standards mode has problems retrieving the className\r\n element.className = value;\r\n\r\n // stroke\r\n }\r\n else if (key === \"stroke\") {\r\n value = renderer.color(value, element, key);\r\n\r\n key = \"strokecolor\";\r\n\r\n // stroke width\r\n }\r\n else if (key === \"stroke-width\" || key === \"strokeWidth\") {\r\n element.stroked = value ? true : false;\r\n key = \"strokeweight\";\r\n wrapper[key] = value; // used in getter, issue #113\r\n if (isNumber(value)) {\r\n value += PX;\r\n }\r\n\r\n // dashStyle\r\n }\r\n else if (key === \"dashstyle\") {\r\n var strokeElem =\r\n element.getElementsByTagName(\"stroke\")[0] ||\r\n createElement(\r\n renderer.prepVML([\"\"]),\r\n null,\r\n null,\r\n element\r\n );\r\n strokeElem[key] = value || \"solid\";\r\n wrapper.dashstyle = value; /* because changing stroke-width will change the dash length\r\n\t\t\t\t\t\t\tand cause an epileptic effect */\r\n skipAttr = true;\r\n\r\n // fill\r\n }\r\n else if (key === \"fill\") {\r\n if (nodeName === \"SPAN\") {\r\n // text color\r\n elemStyle.color = value;\r\n }\r\n else if (nodeName !== \"IMG\") {\r\n // #1336\r\n element.filled = value !== NONE ? true : false;\r\n\r\n value = renderer.color(value, element, key, wrapper);\r\n\r\n key = \"fillcolor\";\r\n }\r\n\r\n // opacity: don't bother - animation is too slow and filters introduce artifacts\r\n }\r\n else if (key === \"opacity\") {\r\n /*css(element, {\r\n\t\t\t\t\t\t\topacity: value\r\n\t\t\t\t\t\t});*/\r\n skipAttr = true;\r\n\r\n // rotation on VML elements\r\n }\r\n else if (nodeName === \"shape\" && key === \"rotation\") {\r\n wrapper[key] = element.style[key] = value; // style is for #1873\r\n\r\n // Correction for the 1x1 size of the shape container. Used in gauge needles.\r\n element.style.left =\r\n -mathRound(mathSin(value * deg2rad) + 1) + PX;\r\n element.style.top = mathRound(mathCos(value * deg2rad)) + PX;\r\n\r\n // translation for animation\r\n }\r\n else if (\r\n key === \"translateX\" ||\r\n key === \"translateY\" ||\r\n key === \"rotation\"\r\n ) {\r\n wrapper[key] = value;\r\n wrapper.updateTransform();\r\n\r\n skipAttr = true;\r\n\r\n // text for rotated and non-rotated elements\r\n }\r\n else if (key === \"text\") {\r\n this.bBox = null;\r\n element.innerHTML = value;\r\n skipAttr = true;\r\n }\r\n\r\n if (!skipAttr) {\r\n if (docMode8) {\r\n // IE8 setAttribute bug\r\n element[key] = value;\r\n }\r\n else {\r\n attr(element, key, value);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n return ret;\r\n },\r\n\r\n /**\r\n * Set the element's clipping to a predefined rectangle\r\n *\r\n * @param {String} id The id of the clip rectangle\r\n */\r\n clip: function(clipRect) {\r\n var wrapper = this,\r\n clipMembers,\r\n cssRet;\r\n\r\n if (clipRect) {\r\n clipMembers = clipRect.members;\r\n erase(clipMembers, wrapper); // Ensure unique list of elements (#1258)\r\n clipMembers.push(wrapper);\r\n wrapper.destroyClip = function() {\r\n erase(clipMembers, wrapper);\r\n };\r\n cssRet = clipRect.getCSS(wrapper);\r\n }\r\n else {\r\n if (wrapper.destroyClip) {\r\n wrapper.destroyClip();\r\n }\r\n cssRet = { clip: docMode8 ? \"inherit\" : \"rect(auto)\" }; // #1214\r\n }\r\n\r\n return wrapper.css(cssRet);\r\n },\r\n\r\n /**\r\n * Set styles for the element\r\n * @param {Object} styles\r\n */\r\n css: SVGElement.prototype.htmlCss,\r\n\r\n /**\r\n * Removes a child either by removeChild or move to garbageBin.\r\n * Issue 490; in VML removeChild results in Orphaned nodes according to sIEve, discardElement does not.\r\n */\r\n safeRemoveChild: function(element) {\r\n // discardElement will detach the node from its parent before attaching it\r\n // to the garbage bin. Therefore it is important that the node is attached and have parent.\r\n if (element.parentNode) {\r\n discardElement(element);\r\n }\r\n },\r\n\r\n /**\r\n * Extend element.destroy by removing it from the clip members array\r\n */\r\n destroy: function() {\r\n if (this.destroyClip) {\r\n this.destroyClip();\r\n }\r\n\r\n return SVGElement.prototype.destroy.apply(this);\r\n },\r\n\r\n /**\r\n * Add an event listener. VML override for normalizing event parameters.\r\n * @param {String} eventType\r\n * @param {Function} handler\r\n */\r\n on: function(eventType, handler) {\r\n // simplest possible event model for internal use\r\n this.element[\"on\" + eventType] = function() {\r\n var evt = win.event;\r\n evt.target = evt.srcElement;\r\n handler(evt);\r\n };\r\n return this;\r\n },\r\n\r\n /**\r\n * In stacked columns, cut off the shadows so that they don't overlap\r\n */\r\n cutOffPath: function(path, length) {\r\n var len;\r\n\r\n path = path.split(/[ ,]/);\r\n len = path.length;\r\n\r\n if (len === 9 || len === 11) {\r\n path[len - 4] = path[len - 2] = pInt(path[len - 2]) - 10 * length;\r\n }\r\n return path.join(\" \");\r\n },\r\n\r\n /**\r\n * Apply a drop shadow by copying elements and giving them different strokes\r\n * @param {Boolean|Object} shadowOptions\r\n */\r\n shadow: function(shadowOptions, group, cutOff) {\r\n var shadows = [],\r\n i,\r\n element = this.element,\r\n renderer = this.renderer,\r\n shadow,\r\n elemStyle = element.style,\r\n markup,\r\n path = element.path,\r\n strokeWidth,\r\n modifiedPath,\r\n shadowWidth,\r\n shadowElementOpacity;\r\n\r\n // some times empty paths are not strings\r\n if (path && typeof path.value !== \"string\") {\r\n path = \"x\";\r\n }\r\n modifiedPath = path;\r\n\r\n if (shadowOptions) {\r\n shadowWidth = pick(shadowOptions.width, 3);\r\n shadowElementOpacity = (shadowOptions.opacity || 0.15) / shadowWidth;\r\n for (i = 1; i <= 3; i++) {\r\n strokeWidth = shadowWidth * 2 + 1 - 2 * i;\r\n\r\n // Cut off shadows for stacked column items\r\n if (cutOff) {\r\n modifiedPath = this.cutOffPath(path.value, strokeWidth + 0.5);\r\n }\r\n\r\n markup = [\r\n ''\r\n ];\r\n\r\n shadow = createElement(renderer.prepVML(markup), null, {\r\n left: pInt(elemStyle.left) + pick(shadowOptions.offsetX, 1),\r\n top: pInt(elemStyle.top) + pick(shadowOptions.offsetY, 1)\r\n });\r\n if (cutOff) {\r\n shadow.cutOff = strokeWidth + 1;\r\n }\r\n\r\n // apply the opacity\r\n markup = [\r\n ''\r\n ];\r\n createElement(renderer.prepVML(markup), null, null, shadow);\r\n\r\n // insert it\r\n if (group) {\r\n group.element.appendChild(shadow);\r\n }\r\n else {\r\n element.parentNode.insertBefore(shadow, element);\r\n }\r\n\r\n // record it\r\n shadows.push(shadow);\r\n }\r\n\r\n this.shadows = shadows;\r\n }\r\n return this;\r\n }\r\n };\r\n VMLElement = extendClass(SVGElement, VMLElement);\r\n\r\n /**\r\n * The VML renderer\r\n */\r\n var VMLRendererExtension = {\r\n // inherit SVGRenderer\r\n\r\n Element: VMLElement,\r\n isIE8: userAgent.indexOf(\"MSIE 8.0\") > -1,\r\n\r\n /**\r\n * Initialize the VMLRenderer\r\n * @param {Object} container\r\n * @param {Number} width\r\n * @param {Number} height\r\n */\r\n init: function(container, width, height) {\r\n var renderer = this,\r\n boxWrapper,\r\n box,\r\n css;\r\n\r\n renderer.alignedObjects = [];\r\n\r\n boxWrapper = renderer.createElement(DIV);\r\n box = boxWrapper.element;\r\n box.style.position = RELATIVE; // for freeform drawing using renderer directly\r\n container.appendChild(boxWrapper.element);\r\n\r\n // generate the containing box\r\n renderer.isVML = true;\r\n renderer.box = box;\r\n renderer.boxWrapper = boxWrapper;\r\n\r\n renderer.setSize(width, height, false);\r\n\r\n // The only way to make IE6 and IE7 print is to use a global namespace. However,\r\n // with IE8 the only way to make the dynamic shapes visible in screen and print mode\r\n // seems to be to add the xmlns attribute and the behaviour style inline.\r\n if (!doc.namespaces.hcv) {\r\n doc.namespaces.add(\"hcv\", \"urn:schemas-microsoft-com:vml\");\r\n\r\n // Setup default CSS (#2153, #2368, #2384)\r\n css =\r\n \"hcv\\\\:fill, hcv\\\\:path, hcv\\\\:shape, hcv\\\\:stroke\" +\r\n \"{ behavior:url(#default#VML); display: inline-block; } \";\r\n try {\r\n doc.createStyleSheet().cssText = css;\r\n }\r\n catch (e) {\r\n doc.styleSheets[0].cssText += css;\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Detect whether the renderer is hidden. This happens when one of the parent elements\r\n * has display: none\r\n */\r\n isHidden: function() {\r\n return !this.box.offsetWidth;\r\n },\r\n\r\n /**\r\n * Define a clipping rectangle. In VML it is accomplished by storing the values\r\n * for setting the CSS style to all associated members.\r\n *\r\n * @param {Number} x\r\n * @param {Number} y\r\n * @param {Number} width\r\n * @param {Number} height\r\n */\r\n clipRect: function(x, y, width, height) {\r\n // create a dummy element\r\n var clipRect = this.createElement(),\r\n isObj = isObject(x);\r\n\r\n // mimic a rectangle with its style object for automatic updating in attr\r\n return extend(clipRect, {\r\n members: [],\r\n left: (isObj ? x.x : x) + 1,\r\n top: (isObj ? x.y : y) + 1,\r\n width: (isObj ? x.width : width) - 1,\r\n height: (isObj ? x.height : height) - 1,\r\n getCSS: function(wrapper) {\r\n var element = wrapper.element,\r\n nodeName = element.nodeName,\r\n isShape = nodeName === \"shape\",\r\n inverted = wrapper.inverted,\r\n rect = this,\r\n top = rect.top - (isShape ? element.offsetTop : 0),\r\n left = rect.left,\r\n right = left + rect.width,\r\n bottom = top + rect.height,\r\n ret = {\r\n clip:\r\n \"rect(\" +\r\n mathRound(inverted ? left : top) +\r\n \"px,\" +\r\n mathRound(inverted ? bottom : right) +\r\n \"px,\" +\r\n mathRound(inverted ? right : bottom) +\r\n \"px,\" +\r\n mathRound(inverted ? top : left) +\r\n \"px)\"\r\n };\r\n\r\n // issue 74 workaround\r\n if (!inverted && docMode8 && nodeName === \"DIV\") {\r\n extend(ret, {\r\n width: right + PX,\r\n height: bottom + PX\r\n });\r\n }\r\n return ret;\r\n },\r\n\r\n // used in attr and animation to update the clipping of all members\r\n updateClipping: function() {\r\n each(clipRect.members, function(member) {\r\n member.css(clipRect.getCSS(member));\r\n });\r\n }\r\n });\r\n },\r\n\r\n /**\r\n * Take a color and return it if it's a string, make it a gradient if it's a\r\n * gradient configuration object, and apply opacity.\r\n *\r\n * @param {Object} color The color or config object\r\n */\r\n color: function(color, elem, prop, wrapper) {\r\n var renderer = this,\r\n colorObject,\r\n regexRgba = /^rgba/,\r\n markup,\r\n fillType,\r\n ret = NONE;\r\n\r\n // Check for linear or radial gradient\r\n if (color && color.linearGradient) {\r\n fillType = \"gradient\";\r\n }\r\n else if (color && color.radialGradient) {\r\n fillType = \"pattern\";\r\n }\r\n\r\n if (fillType) {\r\n var stopColor,\r\n stopOpacity,\r\n gradient = color.linearGradient || color.radialGradient,\r\n x1,\r\n y1,\r\n x2,\r\n y2,\r\n opacity1,\r\n opacity2,\r\n color1,\r\n color2,\r\n fillAttr = \"\",\r\n stops = color.stops,\r\n firstStop,\r\n lastStop,\r\n colors = [],\r\n addFillNode = function() {\r\n // Add the fill subnode. When colors attribute is used, the meanings of opacity and o:opacity2\r\n // are reversed.\r\n markup = [\r\n ''\r\n ];\r\n createElement(renderer.prepVML(markup), null, null, elem);\r\n };\r\n\r\n // Extend from 0 to 1\r\n firstStop = stops[0];\r\n lastStop = stops[stops.length - 1];\r\n if (firstStop[0] > 0) {\r\n stops.unshift([0, firstStop[1]]);\r\n }\r\n if (lastStop[0] < 1) {\r\n stops.push([1, lastStop[1]]);\r\n }\r\n\r\n // Compute the stops\r\n each(stops, function(stop, i) {\r\n if (regexRgba.test(stop[1])) {\r\n colorObject = Color(stop[1]);\r\n stopColor = colorObject.get(\"rgb\");\r\n stopOpacity = colorObject.get(\"a\");\r\n }\r\n else {\r\n stopColor = stop[1];\r\n stopOpacity = 1;\r\n }\r\n\r\n // Build the color attribute\r\n colors.push(stop[0] * 100 + \"% \" + stopColor);\r\n\r\n // Only start and end opacities are allowed, so we use the first and the last\r\n if (!i) {\r\n opacity1 = stopOpacity;\r\n color2 = stopColor;\r\n }\r\n else {\r\n opacity2 = stopOpacity;\r\n color1 = stopColor;\r\n }\r\n });\r\n\r\n // Apply the gradient to fills only.\r\n if (prop === \"fill\") {\r\n // Handle linear gradient angle\r\n if (fillType === \"gradient\") {\r\n x1 = gradient.x1 || gradient[0] || 0;\r\n y1 = gradient.y1 || gradient[1] || 0;\r\n x2 = gradient.x2 || gradient[2] || 0;\r\n y2 = gradient.y2 || gradient[3] || 0;\r\n fillAttr =\r\n 'angle=\"' +\r\n (90 -\r\n (math.atan(\r\n (y2 - y1) / // y vector\r\n (x2 - x1) // x vector\r\n ) *\r\n 180) /\r\n mathPI) +\r\n '\"';\r\n\r\n addFillNode();\r\n\r\n // Radial (circular) gradient\r\n }\r\n else {\r\n var r = gradient.r,\r\n sizex = r * 2,\r\n sizey = r * 2,\r\n cx = gradient.cx,\r\n cy = gradient.cy,\r\n radialReference = elem.radialReference,\r\n bBox,\r\n applyRadialGradient = function() {\r\n if (radialReference) {\r\n bBox = wrapper.getBBox();\r\n cx += (radialReference[0] - bBox.x) / bBox.width - 0.5;\r\n cy += (radialReference[1] - bBox.y) / bBox.height - 0.5;\r\n sizex *= radialReference[2] / bBox.width;\r\n sizey *= radialReference[2] / bBox.height;\r\n }\r\n fillAttr =\r\n 'src=\"' +\r\n defaultOptions.global.VMLRadialGradientURL +\r\n '\" ' +\r\n 'size=\"' +\r\n sizex +\r\n \",\" +\r\n sizey +\r\n '\" ' +\r\n 'origin=\"0.5,0.5\" ' +\r\n 'position=\"' +\r\n cx +\r\n \",\" +\r\n cy +\r\n '\" ' +\r\n 'color2=\"' +\r\n color2 +\r\n '\" ';\r\n\r\n addFillNode();\r\n };\r\n\r\n // Apply radial gradient\r\n if (wrapper.added) {\r\n applyRadialGradient();\r\n }\r\n else {\r\n // We need to know the bounding box to get the size and position right\r\n addEvent(wrapper, \"add\", applyRadialGradient);\r\n }\r\n\r\n // The fill element's color attribute is broken in IE8 standards mode, so we\r\n // need to set the parent shape's fillcolor attribute instead.\r\n ret = color1;\r\n }\r\n\r\n // Gradients are not supported for VML stroke, return the first color. #722.\r\n }\r\n else {\r\n ret = stopColor;\r\n }\r\n\r\n // if the color is an rgba color, split it and add a fill node\r\n // to hold the opacity component\r\n }\r\n else if (regexRgba.test(color) && elem.tagName !== \"IMG\") {\r\n colorObject = Color(color);\r\n\r\n markup = [\"<\", prop, ' opacity=\"', colorObject.get(\"a\"), '\"/>'];\r\n createElement(this.prepVML(markup), null, null, elem);\r\n\r\n ret = colorObject.get(\"rgb\");\r\n }\r\n else {\r\n var propNodes = elem.getElementsByTagName(prop); // 'stroke' or 'fill' node\r\n if (propNodes.length) {\r\n propNodes[0].opacity = 1;\r\n propNodes[0].type = \"solid\";\r\n }\r\n ret = color;\r\n }\r\n\r\n return ret;\r\n },\r\n\r\n /**\r\n * Take a VML string and prepare it for either IE8 or IE6/IE7.\r\n * @param {Array} markup A string array of the VML markup to prepare\r\n */\r\n prepVML: function(markup) {\r\n var vmlStyle = \"display:inline-block;behavior:url(#default#VML);\",\r\n isIE8 = this.isIE8;\r\n\r\n markup = markup.join(\"\");\r\n\r\n if (isIE8) {\r\n // add xmlns and style inline\r\n markup = markup.replace(\r\n \"/>\",\r\n ' xmlns=\"urn:schemas-microsoft-com:vml\" />'\r\n );\r\n if (markup.indexOf('style=\"') === -1) {\r\n markup = markup.replace(\"/>\", ' style=\"' + vmlStyle + '\" />');\r\n }\r\n else {\r\n markup = markup.replace('style=\"', 'style=\"' + vmlStyle);\r\n }\r\n }\r\n else {\r\n // add namespace\r\n markup = markup.replace(\"<\", \" 1) {\r\n obj.attr({\r\n x: x,\r\n y: y,\r\n width: width,\r\n height: height\r\n });\r\n }\r\n return obj;\r\n },\r\n\r\n /**\r\n * VML uses a shape for rect to overcome bugs and rotation problems\r\n */\r\n rect: function(x, y, width, height, r, strokeWidth) {\r\n var wrapper = this.symbol(\"rect\");\r\n wrapper.r = isObject(x) ? x.r : r;\r\n\r\n //return wrapper.attr(wrapper.crisp(strokeWidth, x, y, mathMax(width, 0), mathMax(height, 0)));\r\n return wrapper.attr(\r\n isObject(x)\r\n ? x\r\n : // do not crispify when an object is passed in (as in column charts)\r\n wrapper.crisp(\r\n strokeWidth,\r\n x,\r\n y,\r\n mathMax(width, 0),\r\n mathMax(height, 0)\r\n )\r\n );\r\n },\r\n\r\n /**\r\n * In the VML renderer, each child of an inverted div (group) is inverted\r\n * @param {Object} element\r\n * @param {Object} parentNode\r\n */\r\n invertChild: function(element, parentNode) {\r\n var parentStyle = parentNode.style;\r\n css(element, {\r\n flip: \"x\",\r\n left: pInt(parentStyle.width) - 1,\r\n top: pInt(parentStyle.height) - 1,\r\n rotation: -90\r\n });\r\n },\r\n\r\n /**\r\n * Symbol definitions that override the parent SVG renderer's symbols\r\n *\r\n */\r\n symbols: {\r\n // VML specific arc function\r\n arc: function(x, y, w, h, options) {\r\n var start = options.start,\r\n end = options.end,\r\n radius = options.r || w || h,\r\n innerRadius = options.innerR,\r\n cosStart = mathCos(start),\r\n sinStart = mathSin(start),\r\n cosEnd = mathCos(end),\r\n sinEnd = mathSin(end),\r\n ret;\r\n\r\n if (end - start === 0) {\r\n // no angle, don't show it.\r\n return [\"x\"];\r\n }\r\n\r\n ret = [\r\n \"wa\", // clockwise arc to\r\n x - radius, // left\r\n y - radius, // top\r\n x + radius, // right\r\n y + radius, // bottom\r\n x + radius * cosStart, // start x\r\n y + radius * sinStart, // start y\r\n x + radius * cosEnd, // end x\r\n y + radius * sinEnd // end y\r\n ];\r\n\r\n if (options.open && !innerRadius) {\r\n ret.push(\r\n \"e\",\r\n M,\r\n x, // - innerRadius,\r\n y // - innerRadius\r\n );\r\n }\r\n\r\n ret.push(\r\n \"at\", // anti clockwise arc to\r\n x - innerRadius, // left\r\n y - innerRadius, // top\r\n x + innerRadius, // right\r\n y + innerRadius, // bottom\r\n x + innerRadius * cosEnd, // start x\r\n y + innerRadius * sinEnd, // start y\r\n x + innerRadius * cosStart, // end x\r\n y + innerRadius * sinStart, // end y\r\n \"x\", // finish path\r\n \"e\" // close\r\n );\r\n\r\n ret.isArc = true;\r\n return ret;\r\n },\r\n // Add circle symbol path. This performs significantly faster than v:oval.\r\n circle: function(x, y, w, h, wrapper) {\r\n if (wrapper) {\r\n w = h = 2 * wrapper.r;\r\n }\r\n\r\n // Center correction, #1682\r\n if (wrapper && wrapper.isCircle) {\r\n x -= w / 2;\r\n y -= h / 2;\r\n }\r\n\r\n // Return the path\r\n return [\r\n \"wa\", // clockwisearcto\r\n x, // left\r\n y, // top\r\n x + w, // right\r\n y + h, // bottom\r\n x + w, // start x\r\n y + h / 2, // start y\r\n x + w, // end x\r\n y + h / 2, // end y\r\n //'x', // finish path\r\n \"e\" // close\r\n ];\r\n },\r\n /**\r\n * Add rectangle symbol path which eases rotation and omits arcsize problems\r\n * compared to the built-in VML roundrect shape\r\n *\r\n * @param {Number} left Left position\r\n * @param {Number} top Top position\r\n * @param {Number} r Border radius\r\n * @param {Object} options Width and height\r\n */\r\n\r\n rect: function(left, top, width, height, options) {\r\n var right = left + width,\r\n bottom = top + height,\r\n ret,\r\n r;\r\n\r\n // No radius, return the more lightweight square\r\n if (!defined(options) || !options.r) {\r\n ret = SVGRenderer.prototype.symbols.square.apply(0, arguments);\r\n\r\n // Has radius add arcs for the corners\r\n }\r\n else {\r\n r = mathMin(options.r, width, height);\r\n ret = [\r\n M,\r\n left + r,\r\n top,\r\n\r\n L,\r\n right - r,\r\n top,\r\n \"wa\",\r\n right - 2 * r,\r\n top,\r\n right,\r\n top + 2 * r,\r\n right - r,\r\n top,\r\n right,\r\n top + r,\r\n\r\n L,\r\n right,\r\n bottom - r,\r\n \"wa\",\r\n right - 2 * r,\r\n bottom - 2 * r,\r\n right,\r\n bottom,\r\n right,\r\n bottom - r,\r\n right - r,\r\n bottom,\r\n\r\n L,\r\n left + r,\r\n bottom,\r\n \"wa\",\r\n left,\r\n bottom - 2 * r,\r\n left + 2 * r,\r\n bottom,\r\n left + r,\r\n bottom,\r\n left,\r\n bottom - r,\r\n\r\n L,\r\n left,\r\n top + r,\r\n \"wa\",\r\n left,\r\n top,\r\n left + 2 * r,\r\n top + 2 * r,\r\n left,\r\n top + r,\r\n left + r,\r\n top,\r\n\r\n \"x\",\r\n \"e\"\r\n ];\r\n }\r\n return ret;\r\n }\r\n }\r\n };\r\n Highcharts.VMLRenderer = VMLRenderer = function() {\r\n this.init.apply(this, arguments);\r\n };\r\n VMLRenderer.prototype = merge(SVGRenderer.prototype, VMLRendererExtension);\r\n\r\n // general renderer\r\n Renderer = VMLRenderer;\r\n }\r\n\r\n // This method is used with exporting in old IE, when emulating SVG (see #2314)\r\n SVGRenderer.prototype.measureSpanWidth = function(text, styles) {\r\n var measuringSpan = doc.createElement(\"span\"),\r\n textNode = doc.createTextNode(text);\r\n\r\n measuringSpan.appendChild(textNode);\r\n css(measuringSpan, styles);\r\n this.box.appendChild(measuringSpan);\r\n return measuringSpan.offsetWidth;\r\n };\r\n\r\n /* ****************************************************************************\r\n * *\r\n * END OF INTERNET EXPLORER <= 8 SPECIFIC CODE *\r\n * *\r\n *****************************************************************************/\r\n /* ****************************************************************************\r\n * *\r\n * START OF ANDROID < 3 SPECIFIC CODE. THIS CAN BE REMOVED IF YOU'RE NOT *\r\n * TARGETING THAT SYSTEM. *\r\n * *\r\n *****************************************************************************/\r\n var CanVGRenderer, CanVGController;\r\n\r\n if (useCanVG) {\r\n /**\r\n * The CanVGRenderer is empty from start to keep the source footprint small.\r\n * When requested, the CanVGController downloads the rest of the source packaged\r\n * together with the canvg library.\r\n */\r\n Highcharts.CanVGRenderer = CanVGRenderer = function() {\r\n // Override the global SVG namespace to fake SVG/HTML that accepts CSS\r\n SVG_NS = \"http://www.w3.org/1999/xhtml\";\r\n };\r\n\r\n /**\r\n * Start with an empty symbols object. This is needed when exporting is used (exporting.src.js will add a few symbols), but\r\n * the implementation from SvgRenderer will not be merged in until first render.\r\n */\r\n CanVGRenderer.prototype.symbols = {};\r\n\r\n /**\r\n * Handles on demand download of canvg rendering support.\r\n */\r\n CanVGController = (function() {\r\n // List of renderering calls\r\n var deferredRenderCalls = [];\r\n\r\n /**\r\n * When downloaded, we are ready to draw deferred charts.\r\n */\r\n function drawDeferred() {\r\n var callLength = deferredRenderCalls.length,\r\n callIndex;\r\n\r\n // Draw all pending render calls\r\n for (callIndex = 0; callIndex < callLength; callIndex++) {\r\n deferredRenderCalls[callIndex]();\r\n }\r\n // Clear the list\r\n deferredRenderCalls = [];\r\n }\r\n\r\n return {\r\n push: function(func, scriptLocation) {\r\n // Only get the script once\r\n if (deferredRenderCalls.length === 0) {\r\n getScript(scriptLocation, drawDeferred);\r\n }\r\n // Register render call\r\n deferredRenderCalls.push(func);\r\n }\r\n };\r\n })();\r\n\r\n Renderer = CanVGRenderer;\r\n } // end CanVGRenderer\r\n\r\n /* ****************************************************************************\r\n * *\r\n * END OF ANDROID < 3 SPECIFIC CODE *\r\n * *\r\n *****************************************************************************/\r\n\r\n /**\r\n * The Tick class\r\n */\r\n function Tick(axis, pos, type, noLabel) {\r\n this.axis = axis;\r\n this.pos = pos;\r\n this.type = type || \"\";\r\n this.isNew = true;\r\n\r\n if (!type && !noLabel) {\r\n this.addLabel();\r\n }\r\n }\r\n\r\n Tick.prototype = {\r\n /**\r\n * Write the tick label\r\n */\r\n addLabel: function() {\r\n var tick = this,\r\n axis = tick.axis,\r\n options = axis.options,\r\n chart = axis.chart,\r\n horiz = axis.horiz,\r\n categories = axis.categories,\r\n names = axis.names,\r\n pos = tick.pos,\r\n labelOptions = options.labels,\r\n str,\r\n tickPositions = axis.tickPositions,\r\n width =\r\n (horiz &&\r\n categories &&\r\n !labelOptions.step &&\r\n !labelOptions.staggerLines &&\r\n !labelOptions.rotation &&\r\n chart.plotWidth / tickPositions.length) ||\r\n (!horiz && (chart.margin[3] || chart.chartWidth * 0.33)), // #1580, #1931\r\n isFirst = pos === tickPositions[0],\r\n isLast = pos === tickPositions[tickPositions.length - 1],\r\n css,\r\n attr,\r\n value = categories ? pick(categories[pos], names[pos], pos) : pos,\r\n label = tick.label,\r\n tickPositionInfo = tickPositions.info,\r\n dateTimeLabelFormat;\r\n\r\n // Set the datetime label format. If a higher rank is set for this position, use that. If not,\r\n // use the general format.\r\n if (axis.isDatetimeAxis && tickPositionInfo) {\r\n dateTimeLabelFormat =\r\n options.dateTimeLabelFormats[\r\n tickPositionInfo.higherRanks[pos] || tickPositionInfo.unitName\r\n ];\r\n }\r\n\r\n // set properties for access in render method\r\n tick.isFirst = isFirst;\r\n tick.isLast = isLast;\r\n\r\n // get the string\r\n str = axis.labelFormatter.call({\r\n axis: axis,\r\n chart: chart,\r\n isFirst: isFirst,\r\n isLast: isLast,\r\n dateTimeLabelFormat: dateTimeLabelFormat,\r\n value: axis.isLog ? correctFloat(lin2log(value)) : value\r\n });\r\n\r\n // prepare CSS\r\n css = width && {\r\n width:\r\n mathMax(1, mathRound(width - 2 * (labelOptions.padding || 10))) + PX\r\n };\r\n css = extend(css, labelOptions.style);\r\n\r\n // first call\r\n if (!defined(label)) {\r\n attr = {\r\n align: axis.labelAlign\r\n };\r\n if (isNumber(labelOptions.rotation)) {\r\n attr.rotation = labelOptions.rotation;\r\n }\r\n if (width && labelOptions.ellipsis) {\r\n attr._clipHeight = axis.len / tickPositions.length;\r\n }\r\n\r\n tick.label =\r\n defined(str) && labelOptions.enabled\r\n ? chart.renderer\r\n .text(str, 0, 0, labelOptions.useHTML)\r\n .attr(attr)\r\n // without position absolute, IE export sometimes is wrong\r\n .css(css)\r\n .add(axis.labelGroup)\r\n : null;\r\n\r\n // update\r\n }\r\n else if (label) {\r\n label\r\n .attr({\r\n text: str\r\n })\r\n .css(css);\r\n }\r\n },\r\n\r\n /**\r\n * Get the offset height or width of the label\r\n */\r\n getLabelSize: function() {\r\n var label = this.label,\r\n axis = this.axis;\r\n return label\r\n ? (this.labelBBox = label.getBBox())[axis.horiz ? \"height\" : \"width\"]\r\n : 0;\r\n },\r\n\r\n /**\r\n * Find how far the labels extend to the right and left of the tick's x position. Used for anti-collision\r\n * detection with overflow logic.\r\n */\r\n getLabelSides: function() {\r\n var bBox = this.labelBBox, // assume getLabelSize has run at this point\r\n axis = this.axis,\r\n options = axis.options,\r\n labelOptions = options.labels,\r\n width = bBox.width,\r\n leftSide =\r\n width * { left: 0, center: 0.5, right: 1 }[axis.labelAlign] -\r\n labelOptions.x;\r\n\r\n return [-leftSide, width - leftSide];\r\n },\r\n\r\n /**\r\n * Handle the label overflow by adjusting the labels to the left and right edge, or\r\n * hide them if they collide into the neighbour label.\r\n */\r\n handleOverflow: function(index, xy) {\r\n var show = true,\r\n axis = this.axis,\r\n chart = axis.chart,\r\n isFirst = this.isFirst,\r\n isLast = this.isLast,\r\n x = xy.x,\r\n reversed = axis.reversed,\r\n tickPositions = axis.tickPositions;\r\n\r\n if (isFirst || isLast) {\r\n var sides = this.getLabelSides(),\r\n leftSide = sides[0],\r\n rightSide = sides[1],\r\n plotLeft = chart.plotLeft,\r\n plotRight = plotLeft + axis.len,\r\n neighbour = axis.ticks[tickPositions[index + (isFirst ? 1 : -1)]],\r\n neighbourEdge =\r\n neighbour &&\r\n neighbour.label.xy &&\r\n neighbour.label.xy.x + neighbour.getLabelSides()[isFirst ? 0 : 1];\r\n\r\n if ((isFirst && !reversed) || (isLast && reversed)) {\r\n // Is the label spilling out to the left of the plot area?\r\n if (x + leftSide < plotLeft) {\r\n // Align it to plot left\r\n x = plotLeft - leftSide;\r\n\r\n // Hide it if it now overlaps the neighbour label\r\n if (neighbour && x + rightSide > neighbourEdge) {\r\n show = false;\r\n }\r\n }\r\n }\r\n else {\r\n // Is the label spilling out to the right of the plot area?\r\n if (x + rightSide > plotRight) {\r\n // Align it to plot right\r\n x = plotRight - rightSide;\r\n\r\n // Hide it if it now overlaps the neighbour label\r\n if (neighbour && x + leftSide < neighbourEdge) {\r\n show = false;\r\n }\r\n }\r\n }\r\n\r\n // Set the modified x position of the label\r\n xy.x = x;\r\n }\r\n return show;\r\n },\r\n\r\n /**\r\n * Get the x and y position for ticks and labels\r\n */\r\n getPosition: function(horiz, pos, tickmarkOffset, old) {\r\n var axis = this.axis,\r\n chart = axis.chart,\r\n cHeight = (old && chart.oldChartHeight) || chart.chartHeight;\r\n\r\n return {\r\n x: horiz\r\n ? axis.translate(pos + tickmarkOffset, null, null, old) + axis.transB\r\n : axis.left +\r\n axis.offset +\r\n (axis.opposite\r\n ? ((old && chart.oldChartWidth) || chart.chartWidth) -\r\n axis.right -\r\n axis.left\r\n : 0),\r\n\r\n y: horiz\r\n ? cHeight -\r\n axis.bottom +\r\n axis.offset -\r\n (axis.opposite ? axis.height : 0)\r\n : cHeight -\r\n axis.translate(pos + tickmarkOffset, null, null, old) -\r\n axis.transB\r\n };\r\n },\r\n\r\n /**\r\n * Get the x, y position of the tick label\r\n */\r\n getLabelPosition: function(\r\n x,\r\n y,\r\n label,\r\n horiz,\r\n labelOptions,\r\n tickmarkOffset,\r\n index,\r\n step\r\n ) {\r\n var axis = this.axis,\r\n transA = axis.transA,\r\n reversed = axis.reversed,\r\n staggerLines = axis.staggerLines,\r\n baseline = axis.chart.renderer.fontMetrics(labelOptions.style.fontSize)\r\n .b,\r\n rotation = labelOptions.rotation;\r\n\r\n x =\r\n x +\r\n labelOptions.x -\r\n (tickmarkOffset && horiz\r\n ? tickmarkOffset * transA * (reversed ? -1 : 1)\r\n : 0);\r\n y =\r\n y +\r\n labelOptions.y -\r\n (tickmarkOffset && !horiz\r\n ? tickmarkOffset * transA * (reversed ? 1 : -1)\r\n : 0);\r\n\r\n // Correct for rotation (#1764)\r\n if (rotation && axis.side === 2) {\r\n y -= baseline - baseline * mathCos(rotation * deg2rad);\r\n }\r\n\r\n // Vertically centered\r\n if (!defined(labelOptions.y) && !rotation) {\r\n // #1951\r\n y += baseline - label.getBBox().height / 2;\r\n }\r\n\r\n // Correct for staggered labels\r\n if (staggerLines) {\r\n y +=\r\n ((index / (step || 1)) % staggerLines) *\r\n (axis.labelOffset / staggerLines);\r\n }\r\n\r\n return {\r\n x: x,\r\n y: y\r\n };\r\n },\r\n\r\n /**\r\n * Extendible method to return the path of the marker\r\n */\r\n getMarkPath: function(x, y, tickLength, tickWidth, horiz, renderer) {\r\n return renderer.crispLine(\r\n [\r\n M,\r\n x,\r\n y,\r\n L,\r\n x + (horiz ? 0 : -tickLength),\r\n y + (horiz ? tickLength : 0)\r\n ],\r\n tickWidth\r\n );\r\n },\r\n\r\n /**\r\n * Put everything in place\r\n *\r\n * @param index {Number}\r\n * @param old {Boolean} Use old coordinates to prepare an animation into new position\r\n */\r\n render: function(index, old, opacity) {\r\n var tick = this,\r\n axis = tick.axis,\r\n options = axis.options,\r\n chart = axis.chart,\r\n renderer = chart.renderer,\r\n horiz = axis.horiz,\r\n type = tick.type,\r\n label = tick.label,\r\n pos = tick.pos,\r\n labelOptions = options.labels,\r\n gridLine = tick.gridLine,\r\n gridPrefix = type ? type + \"Grid\" : \"grid\",\r\n tickPrefix = type ? type + \"Tick\" : \"tick\",\r\n gridLineWidth = options[gridPrefix + \"LineWidth\"],\r\n gridLineColor = options[gridPrefix + \"LineColor\"],\r\n dashStyle = options[gridPrefix + \"LineDashStyle\"],\r\n tickLength = options[tickPrefix + \"Length\"],\r\n tickWidth = options[tickPrefix + \"Width\"] || 0,\r\n tickColor = options[tickPrefix + \"Color\"],\r\n tickPosition = options[tickPrefix + \"Position\"],\r\n gridLinePath,\r\n mark = tick.mark,\r\n markPath,\r\n step = labelOptions.step,\r\n attribs,\r\n show = true,\r\n tickmarkOffset = axis.tickmarkOffset,\r\n xy = tick.getPosition(horiz, pos, tickmarkOffset, old),\r\n x = xy.x,\r\n y = xy.y,\r\n reverseCrisp =\r\n (horiz && x === axis.pos + axis.len) || (!horiz && y === axis.pos)\r\n ? -1\r\n : 1, // #1480, #1687\r\n staggerLines = axis.staggerLines;\r\n\r\n this.isActive = true;\r\n\r\n // create the grid line\r\n if (gridLineWidth) {\r\n gridLinePath = axis.getPlotLinePath(\r\n pos + tickmarkOffset,\r\n gridLineWidth * reverseCrisp,\r\n old,\r\n true\r\n );\r\n\r\n if (gridLine === UNDEFINED) {\r\n attribs = {\r\n stroke: gridLineColor,\r\n \"stroke-width\": gridLineWidth\r\n };\r\n if (dashStyle) {\r\n attribs.dashstyle = dashStyle;\r\n }\r\n if (!type) {\r\n attribs.zIndex = 1;\r\n }\r\n if (old) {\r\n attribs.opacity = 0;\r\n }\r\n tick.gridLine = gridLine = gridLineWidth\r\n ? renderer\r\n .path(gridLinePath)\r\n .attr(attribs)\r\n .add(axis.gridGroup)\r\n : null;\r\n }\r\n\r\n // If the parameter 'old' is set, the current call will be followed\r\n // by another call, therefore do not do any animations this time\r\n if (!old && gridLine && gridLinePath) {\r\n gridLine[tick.isNew ? \"attr\" : \"animate\"]({\r\n d: gridLinePath,\r\n opacity: opacity\r\n });\r\n }\r\n }\r\n\r\n // create the tick mark\r\n if (tickWidth && tickLength) {\r\n // negate the length\r\n if (tickPosition === \"inside\") {\r\n tickLength = -tickLength;\r\n }\r\n if (axis.opposite) {\r\n tickLength = -tickLength;\r\n }\r\n\r\n markPath = tick.getMarkPath(\r\n x,\r\n y,\r\n tickLength,\r\n tickWidth * reverseCrisp,\r\n horiz,\r\n renderer\r\n );\r\n\r\n if (mark) {\r\n // updating\r\n mark.animate({\r\n d: markPath,\r\n opacity: opacity\r\n });\r\n }\r\n else {\r\n // first time\r\n tick.mark = renderer\r\n .path(markPath)\r\n .attr({\r\n stroke: tickColor,\r\n \"stroke-width\": tickWidth,\r\n opacity: opacity\r\n })\r\n .add(axis.axisGroup);\r\n }\r\n }\r\n\r\n // the label is created on init - now move it into place\r\n if (label && !isNaN(x)) {\r\n label.xy = xy = tick.getLabelPosition(\r\n x,\r\n y,\r\n label,\r\n horiz,\r\n labelOptions,\r\n tickmarkOffset,\r\n index,\r\n step\r\n );\r\n\r\n // Apply show first and show last. If the tick is both first and last, it is\r\n // a single centered tick, in which case we show the label anyway (#2100).\r\n if (\r\n (tick.isFirst && !tick.isLast && !pick(options.showFirstLabel, 1)) ||\r\n (tick.isLast && !tick.isFirst && !pick(options.showLastLabel, 1))\r\n ) {\r\n show = false;\r\n\r\n // Handle label overflow and show or hide accordingly\r\n }\r\n else if (\r\n !staggerLines &&\r\n horiz &&\r\n labelOptions.overflow === \"justify\" &&\r\n !tick.handleOverflow(index, xy)\r\n ) {\r\n show = false;\r\n }\r\n\r\n // apply step\r\n if (step && index % step) {\r\n // show those indices dividable by step\r\n show = false;\r\n }\r\n\r\n // Set the new position, and show or hide\r\n if (show && !isNaN(xy.y)) {\r\n xy.opacity = opacity;\r\n label[tick.isNew ? \"attr\" : \"animate\"](xy);\r\n tick.isNew = false;\r\n }\r\n else {\r\n label.attr(\"y\", -9999); // #1338\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Destructor for the tick prototype\r\n */\r\n destroy: function() {\r\n destroyObjectProperties(this, this.axis);\r\n }\r\n };\r\n\r\n /**\r\n * The object wrapper for plot lines and plot bands\r\n * @param {Object} options\r\n */\r\n function PlotLineOrBand(axis, options) {\r\n this.axis = axis;\r\n\r\n if (options) {\r\n this.options = options;\r\n this.id = options.id;\r\n }\r\n }\r\n\r\n PlotLineOrBand.prototype = {\r\n /**\r\n * Render the plot line or plot band. If it is already existing,\r\n * move it.\r\n */\r\n render: function() {\r\n var plotLine = this,\r\n axis = plotLine.axis,\r\n horiz = axis.horiz,\r\n halfPointRange = (axis.pointRange || 0) / 2,\r\n options = plotLine.options,\r\n optionsLabel = options.label,\r\n label = plotLine.label,\r\n width = options.width,\r\n to = options.to,\r\n from = options.from,\r\n isBand = defined(from) && defined(to),\r\n value = options.value,\r\n dashStyle = options.dashStyle,\r\n svgElem = plotLine.svgElem,\r\n path = [],\r\n addEvent,\r\n eventType,\r\n xs,\r\n ys,\r\n x,\r\n y,\r\n color = options.color,\r\n zIndex = options.zIndex,\r\n events = options.events,\r\n attribs,\r\n renderer = axis.chart.renderer;\r\n\r\n // logarithmic conversion\r\n if (axis.isLog) {\r\n from = log2lin(from);\r\n to = log2lin(to);\r\n value = log2lin(value);\r\n }\r\n\r\n // plot line\r\n if (width) {\r\n path = axis.getPlotLinePath(value, width);\r\n attribs = {\r\n stroke: color,\r\n \"stroke-width\": width\r\n };\r\n if (dashStyle) {\r\n attribs.dashstyle = dashStyle;\r\n }\r\n }\r\n else if (isBand) {\r\n // plot band\r\n\r\n // keep within plot area\r\n from = mathMax(from, axis.min - halfPointRange);\r\n to = mathMin(to, axis.max + halfPointRange);\r\n\r\n path = axis.getPlotBandPath(from, to, options);\r\n attribs = {\r\n fill: color\r\n };\r\n if (options.borderWidth) {\r\n attribs.stroke = options.borderColor;\r\n attribs[\"stroke-width\"] = options.borderWidth;\r\n }\r\n }\r\n else {\r\n return;\r\n }\r\n // zIndex\r\n if (defined(zIndex)) {\r\n attribs.zIndex = zIndex;\r\n }\r\n\r\n // common for lines and bands\r\n if (svgElem) {\r\n if (path) {\r\n svgElem.animate(\r\n {\r\n d: path\r\n },\r\n null,\r\n svgElem.onGetPath\r\n );\r\n }\r\n else {\r\n svgElem.hide();\r\n svgElem.onGetPath = function() {\r\n svgElem.show();\r\n };\r\n if (label) {\r\n plotLine.label = label = label.destroy();\r\n }\r\n }\r\n }\r\n else if (path && path.length) {\r\n plotLine.svgElem = svgElem = renderer\r\n .path(path)\r\n .attr(attribs)\r\n .add();\r\n\r\n // events\r\n if (events) {\r\n addEvent = function(eventType) {\r\n svgElem.on(eventType, function(e) {\r\n events[eventType].apply(plotLine, [e]);\r\n });\r\n };\r\n for (eventType in events) {\r\n addEvent(eventType);\r\n }\r\n }\r\n }\r\n\r\n // the plot band/line label\r\n if (\r\n optionsLabel &&\r\n defined(optionsLabel.text) &&\r\n path &&\r\n path.length &&\r\n axis.width > 0 &&\r\n axis.height > 0\r\n ) {\r\n // apply defaults\r\n optionsLabel = merge(\r\n {\r\n align: horiz && isBand && \"center\",\r\n x: horiz ? !isBand && 4 : 10,\r\n verticalAlign: !horiz && isBand && \"middle\",\r\n y: horiz ? (isBand ? 16 : 10) : isBand ? 6 : -4,\r\n rotation: horiz && !isBand && 90\r\n },\r\n optionsLabel\r\n );\r\n\r\n // add the SVG element\r\n if (!label) {\r\n plotLine.label = label = renderer\r\n .text(optionsLabel.text, 0, 0, optionsLabel.useHTML)\r\n .attr({\r\n align: optionsLabel.textAlign || optionsLabel.align,\r\n rotation: optionsLabel.rotation,\r\n zIndex: zIndex\r\n })\r\n .css(optionsLabel.style)\r\n .add();\r\n }\r\n\r\n // get the bounding box and align the label\r\n xs = [path[1], path[4], pick(path[6], path[1])];\r\n ys = [path[2], path[5], pick(path[7], path[2])];\r\n x = arrayMin(xs);\r\n y = arrayMin(ys);\r\n\r\n label.align(optionsLabel, false, {\r\n x: x,\r\n y: y,\r\n width: arrayMax(xs) - x,\r\n height: arrayMax(ys) - y\r\n });\r\n label.show();\r\n }\r\n else if (label) {\r\n // move out of sight\r\n label.hide();\r\n }\r\n\r\n // chainable\r\n return plotLine;\r\n },\r\n\r\n /**\r\n * Remove the plot line or band\r\n */\r\n destroy: function() {\r\n // remove it from the lookup\r\n erase(this.axis.plotLinesAndBands, this);\r\n\r\n delete this.axis;\r\n destroyObjectProperties(this);\r\n }\r\n };\r\n /**\r\n * The class for stack items\r\n */\r\n function StackItem(axis, options, isNegative, x, stackOption, stacking) {\r\n var inverted = axis.chart.inverted;\r\n\r\n this.axis = axis;\r\n\r\n // Tells if the stack is negative\r\n this.isNegative = isNegative;\r\n\r\n // Save the options to be able to style the label\r\n this.options = options;\r\n\r\n // Save the x value to be able to position the label later\r\n this.x = x;\r\n\r\n // Initialize total value\r\n this.total = null;\r\n\r\n // This will keep each points' extremes stored by series.index\r\n this.points = {};\r\n\r\n // Save the stack option on the series configuration object, and whether to treat it as percent\r\n this.stack = stackOption;\r\n this.percent = stacking === \"percent\";\r\n\r\n // The align options and text align varies on whether the stack is negative and\r\n // if the chart is inverted or not.\r\n // First test the user supplied value, then use the dynamic.\r\n this.alignOptions = {\r\n align:\r\n options.align ||\r\n (inverted ? (isNegative ? \"left\" : \"right\") : \"center\"),\r\n verticalAlign:\r\n options.verticalAlign ||\r\n (inverted ? \"middle\" : isNegative ? \"bottom\" : \"top\"),\r\n y: pick(options.y, inverted ? 4 : isNegative ? 14 : -6),\r\n x: pick(options.x, inverted ? (isNegative ? -6 : 6) : 0)\r\n };\r\n\r\n this.textAlign =\r\n options.textAlign ||\r\n (inverted ? (isNegative ? \"right\" : \"left\") : \"center\");\r\n }\r\n\r\n StackItem.prototype = {\r\n destroy: function() {\r\n destroyObjectProperties(this, this.axis);\r\n },\r\n\r\n /**\r\n * Renders the stack total label and adds it to the stack label group.\r\n */\r\n render: function(group) {\r\n var options = this.options,\r\n formatOption = options.format,\r\n str = formatOption\r\n ? format(formatOption, this)\r\n : options.formatter.call(this); // format the text in the label\r\n\r\n // Change the text to reflect the new total and set visibility to hidden in case the serie is hidden\r\n if (this.label) {\r\n this.label.attr({ text: str, visibility: HIDDEN });\r\n // Create new label\r\n }\r\n else {\r\n this.label = this.axis.chart.renderer\r\n .text(str, 0, 0, options.useHTML) // dummy positions, actual position updated with setOffset method in columnseries\r\n .css(options.style) // apply style\r\n .attr({\r\n align: this.textAlign, // fix the text-anchor\r\n rotation: options.rotation, // rotation\r\n visibility: HIDDEN // hidden until setOffset is called\r\n })\r\n .add(group); // add to the labels-group\r\n }\r\n },\r\n\r\n /**\r\n * Sets the offset that the stack has from the x value and repositions the label.\r\n */\r\n setOffset: function(xOffset, xWidth) {\r\n var stackItem = this,\r\n axis = stackItem.axis,\r\n chart = axis.chart,\r\n inverted = chart.inverted,\r\n neg = this.isNegative, // special treatment is needed for negative stacks\r\n y = axis.translate(this.percent ? 100 : this.total, 0, 0, 0, 1), // stack value translated mapped to chart coordinates\r\n yZero = axis.translate(0), // stack origin\r\n h = mathAbs(y - yZero), // stack height\r\n x = chart.xAxis[0].translate(this.x) + xOffset, // stack x position\r\n plotHeight = chart.plotHeight,\r\n stackBox = {\r\n // this is the box for the complete stack\r\n x: inverted ? (neg ? y : y - h) : x,\r\n y: inverted\r\n ? plotHeight - x - xWidth\r\n : neg\r\n ? plotHeight - y - h\r\n : plotHeight - y,\r\n width: inverted ? h : xWidth,\r\n height: inverted ? xWidth : h\r\n },\r\n label = this.label,\r\n alignAttr;\r\n\r\n if (label) {\r\n label.align(this.alignOptions, null, stackBox); // align the label to the box\r\n\r\n // Set visibility (#678)\r\n alignAttr = label.alignAttr;\r\n label.attr({\r\n visibility:\r\n this.options.crop === false ||\r\n chart.isInsidePlot(alignAttr.x, alignAttr.y)\r\n ? hasSVG\r\n ? \"inherit\"\r\n : VISIBLE\r\n : HIDDEN\r\n });\r\n }\r\n }\r\n };\r\n /**\r\n * Create a new axis object\r\n * @param {Object} chart\r\n * @param {Object} options\r\n */\r\n function Axis() {\r\n this.init.apply(this, arguments);\r\n }\r\n\r\n Axis.prototype = {\r\n /**\r\n * Default options for the X axis - the Y axis has extended defaults\r\n */\r\n defaultOptions: {\r\n // allowDecimals: null,\r\n // alternateGridColor: null,\r\n // categories: [],\r\n dateTimeLabelFormats: {\r\n millisecond: \"%H:%M:%S.%L\",\r\n second: \"%H:%M:%S\",\r\n minute: \"%H:%M\",\r\n hour: \"%H:%M\",\r\n day: \"%e. %b\",\r\n week: \"%e. %b\",\r\n month: \"%b '%y\",\r\n year: \"%Y\"\r\n },\r\n endOnTick: false,\r\n gridLineColor: \"#C0C0C0\",\r\n // gridLineDashStyle: 'solid',\r\n // gridLineWidth: 0,\r\n // reversed: false,\r\n\r\n labels: defaultLabelOptions,\r\n // { step: null },\r\n lineColor: \"#C0D0E0\",\r\n lineWidth: 1,\r\n //linkedTo: null,\r\n //max: undefined,\r\n //min: undefined,\r\n minPadding: 0.01,\r\n maxPadding: 0.01,\r\n //minRange: null,\r\n minorGridLineColor: \"#E0E0E0\",\r\n // minorGridLineDashStyle: null,\r\n minorGridLineWidth: 1,\r\n minorTickColor: \"#A0A0A0\",\r\n //minorTickInterval: null,\r\n minorTickLength: 2,\r\n minorTickPosition: \"outside\", // inside or outside\r\n //minorTickWidth: 0,\r\n //opposite: false,\r\n //offset: 0,\r\n //plotBands: [{\r\n //\tevents: {},\r\n //\tzIndex: 1,\r\n //\tlabels: { align, x, verticalAlign, y, style, rotation, textAlign }\r\n //}],\r\n //plotLines: [{\r\n //\tevents: {}\r\n // dashStyle: {}\r\n //\tzIndex:\r\n //\tlabels: { align, x, verticalAlign, y, style, rotation, textAlign }\r\n //}],\r\n //reversed: false,\r\n // showFirstLabel: true,\r\n // showLastLabel: true,\r\n startOfWeek: 1,\r\n startOnTick: false,\r\n tickColor: \"#C0D0E0\",\r\n //tickInterval: null,\r\n tickLength: 5,\r\n tickmarkPlacement: \"between\", // on or between\r\n tickPixelInterval: 100,\r\n tickPosition: \"outside\",\r\n tickWidth: 1,\r\n title: {\r\n //text: null,\r\n align: \"middle\", // low, middle or high\r\n //margin: 0 for horizontal, 10 for vertical axes,\r\n //rotation: 0,\r\n //side: 'outside',\r\n style: {\r\n color: \"#4d759e\",\r\n //font: defaultFont.replace('normal', 'bold')\r\n fontWeight: \"bold\"\r\n }\r\n //x: 0,\r\n //y: 0\r\n },\r\n type: \"linear\" // linear, logarithmic or datetime\r\n },\r\n\r\n /**\r\n * This options set extends the defaultOptions for Y axes\r\n */\r\n defaultYAxisOptions: {\r\n endOnTick: true,\r\n gridLineWidth: 1,\r\n tickPixelInterval: 72,\r\n showLastLabel: true,\r\n labels: {\r\n x: -8,\r\n y: 3\r\n },\r\n lineWidth: 0,\r\n maxPadding: 0.05,\r\n minPadding: 0.05,\r\n startOnTick: true,\r\n tickWidth: 0,\r\n title: {\r\n rotation: 270,\r\n text: \"Values\"\r\n },\r\n stackLabels: {\r\n enabled: false,\r\n //align: dynamic,\r\n //y: dynamic,\r\n //x: dynamic,\r\n //verticalAlign: dynamic,\r\n //textAlign: dynamic,\r\n //rotation: 0,\r\n formatter: function() {\r\n return numberFormat(this.total, -1);\r\n },\r\n style: defaultLabelOptions.style\r\n }\r\n },\r\n\r\n /**\r\n * These options extend the defaultOptions for left axes\r\n */\r\n defaultLeftAxisOptions: {\r\n labels: {\r\n x: -8,\r\n y: null\r\n },\r\n title: {\r\n rotation: 270\r\n }\r\n },\r\n\r\n /**\r\n * These options extend the defaultOptions for right axes\r\n */\r\n defaultRightAxisOptions: {\r\n labels: {\r\n x: 8,\r\n y: null\r\n },\r\n title: {\r\n rotation: 90\r\n }\r\n },\r\n\r\n /**\r\n * These options extend the defaultOptions for bottom axes\r\n */\r\n defaultBottomAxisOptions: {\r\n labels: {\r\n x: 0,\r\n y: 14\r\n // overflow: undefined,\r\n // staggerLines: null\r\n },\r\n title: {\r\n rotation: 0\r\n }\r\n },\r\n /**\r\n * These options extend the defaultOptions for left axes\r\n */\r\n defaultTopAxisOptions: {\r\n labels: {\r\n x: 0,\r\n y: -5\r\n // overflow: undefined\r\n // staggerLines: null\r\n },\r\n title: {\r\n rotation: 0\r\n }\r\n },\r\n\r\n /**\r\n * Initialize the axis\r\n */\r\n init: function(chart, userOptions) {\r\n var isXAxis = userOptions.isX,\r\n axis = this;\r\n\r\n // Flag, is the axis horizontal\r\n axis.horiz = chart.inverted ? !isXAxis : isXAxis;\r\n\r\n // Flag, isXAxis\r\n axis.isXAxis = isXAxis;\r\n axis.xOrY = isXAxis ? \"x\" : \"y\";\r\n\r\n axis.opposite = userOptions.opposite; // needed in setOptions\r\n axis.side = axis.horiz\r\n ? axis.opposite\r\n ? 0\r\n : 2 // top : bottom\r\n : axis.opposite\r\n ? 1\r\n : 3; // right : left\r\n\r\n axis.setOptions(userOptions);\r\n\r\n var options = this.options,\r\n type = options.type,\r\n isDatetimeAxis = type === \"datetime\";\r\n\r\n axis.labelFormatter =\r\n options.labels.formatter || axis.defaultLabelFormatter; // can be overwritten by dynamic format\r\n\r\n // Flag, stagger lines or not\r\n axis.userOptions = userOptions;\r\n\r\n //axis.axisTitleMargin = UNDEFINED,// = options.title.margin,\r\n axis.minPixelPadding = 0;\r\n //axis.ignoreMinPadding = UNDEFINED; // can be set to true by a column or bar series\r\n //axis.ignoreMaxPadding = UNDEFINED;\r\n\r\n axis.chart = chart;\r\n axis.reversed = options.reversed;\r\n axis.zoomEnabled = options.zoomEnabled !== false;\r\n\r\n // Initial categories\r\n axis.categories = options.categories || type === \"category\";\r\n axis.names = [];\r\n\r\n // Elements\r\n //axis.axisGroup = UNDEFINED;\r\n //axis.gridGroup = UNDEFINED;\r\n //axis.axisTitle = UNDEFINED;\r\n //axis.axisLine = UNDEFINED;\r\n\r\n // Shorthand types\r\n axis.isLog = type === \"logarithmic\";\r\n axis.isDatetimeAxis = isDatetimeAxis;\r\n\r\n // Flag, if axis is linked to another axis\r\n axis.isLinked = defined(options.linkedTo);\r\n // Linked axis.\r\n //axis.linkedParent = UNDEFINED;\r\n\r\n // Tick positions\r\n //axis.tickPositions = UNDEFINED; // array containing predefined positions\r\n // Tick intervals\r\n //axis.tickInterval = UNDEFINED;\r\n //axis.minorTickInterval = UNDEFINED;\r\n\r\n axis.tickmarkOffset =\r\n axis.categories && options.tickmarkPlacement === \"between\" ? 0.5 : 0;\r\n\r\n // Major ticks\r\n axis.ticks = {};\r\n // Minor ticks\r\n axis.minorTicks = {};\r\n //axis.tickAmount = UNDEFINED;\r\n\r\n // List of plotLines/Bands\r\n axis.plotLinesAndBands = [];\r\n\r\n // Alternate bands\r\n axis.alternateBands = {};\r\n\r\n // Axis metrics\r\n //axis.left = UNDEFINED;\r\n //axis.top = UNDEFINED;\r\n //axis.width = UNDEFINED;\r\n //axis.height = UNDEFINED;\r\n //axis.bottom = UNDEFINED;\r\n //axis.right = UNDEFINED;\r\n //axis.transA = UNDEFINED;\r\n //axis.transB = UNDEFINED;\r\n //axis.oldTransA = UNDEFINED;\r\n axis.len = 0;\r\n //axis.oldMin = UNDEFINED;\r\n //axis.oldMax = UNDEFINED;\r\n //axis.oldUserMin = UNDEFINED;\r\n //axis.oldUserMax = UNDEFINED;\r\n //axis.oldAxisLength = UNDEFINED;\r\n axis.minRange = axis.userMinRange = options.minRange || options.maxZoom;\r\n axis.range = options.range;\r\n axis.offset = options.offset || 0;\r\n\r\n // Dictionary for stacks\r\n axis.stacks = {};\r\n axis.oldStacks = {};\r\n\r\n // Dictionary for stacks max values\r\n axis.stackExtremes = {};\r\n\r\n // Min and max in the data\r\n //axis.dataMin = UNDEFINED,\r\n //axis.dataMax = UNDEFINED,\r\n\r\n // The axis range\r\n axis.max = null;\r\n axis.min = null;\r\n\r\n // User set min and max\r\n //axis.userMin = UNDEFINED,\r\n //axis.userMax = UNDEFINED,\r\n\r\n // Run Axis\r\n\r\n var eventType,\r\n events = axis.options.events;\r\n\r\n // Register\r\n if (inArray(axis, chart.axes) === -1) {\r\n // don't add it again on Axis.update()\r\n chart.axes.push(axis);\r\n chart[isXAxis ? \"xAxis\" : \"yAxis\"].push(axis);\r\n }\r\n\r\n axis.series = axis.series || []; // populated by Series\r\n\r\n // inverted charts have reversed xAxes as default\r\n if (chart.inverted && isXAxis && axis.reversed === UNDEFINED) {\r\n axis.reversed = true;\r\n }\r\n\r\n axis.removePlotBand = axis.removePlotBandOrLine;\r\n axis.removePlotLine = axis.removePlotBandOrLine;\r\n\r\n // register event listeners\r\n for (eventType in events) {\r\n addEvent(axis, eventType, events[eventType]);\r\n }\r\n\r\n // extend logarithmic axis\r\n if (axis.isLog) {\r\n axis.val2lin = log2lin;\r\n axis.lin2val = lin2log;\r\n }\r\n },\r\n\r\n /**\r\n * Merge and set options\r\n */\r\n setOptions: function(userOptions) {\r\n this.options = merge(\r\n this.defaultOptions,\r\n this.isXAxis ? {} : this.defaultYAxisOptions,\r\n [\r\n this.defaultTopAxisOptions,\r\n this.defaultRightAxisOptions,\r\n this.defaultBottomAxisOptions,\r\n this.defaultLeftAxisOptions\r\n ][this.side],\r\n merge(\r\n defaultOptions[this.isXAxis ? \"xAxis\" : \"yAxis\"], // if set in setOptions (#1053)\r\n userOptions\r\n )\r\n );\r\n },\r\n\r\n /**\r\n * Update the axis with a new options structure\r\n */\r\n update: function(newOptions, redraw) {\r\n var chart = this.chart;\r\n\r\n newOptions = chart.options[this.xOrY + \"Axis\"][\r\n this.options.index\r\n ] = merge(this.userOptions, newOptions);\r\n\r\n this.destroy(true);\r\n this._addedPlotLB = this.userMin = this.userMax = UNDEFINED; // #1611, #2306\r\n\r\n this.init(chart, extend(newOptions, { events: UNDEFINED }));\r\n\r\n chart.isDirtyBox = true;\r\n if (pick(redraw, true)) {\r\n chart.redraw();\r\n }\r\n },\r\n\r\n /**\r\n * Remove the axis from the chart\r\n */\r\n remove: function(redraw) {\r\n var chart = this.chart,\r\n key = this.xOrY + \"Axis\"; // xAxis or yAxis\r\n\r\n // Remove associated series\r\n each(this.series, function(series) {\r\n series.remove(false);\r\n });\r\n\r\n // Remove the axis\r\n erase(chart.axes, this);\r\n erase(chart[key], this);\r\n chart.options[key].splice(this.options.index, 1);\r\n each(chart[key], function(axis, i) {\r\n // Re-index, #1706\r\n axis.options.index = i;\r\n });\r\n this.destroy();\r\n chart.isDirtyBox = true;\r\n\r\n if (pick(redraw, true)) {\r\n chart.redraw();\r\n }\r\n },\r\n\r\n /**\r\n * The default label formatter. The context is a special config object for the label.\r\n */\r\n defaultLabelFormatter: function() {\r\n var axis = this.axis,\r\n value = this.value,\r\n categories = axis.categories,\r\n dateTimeLabelFormat = this.dateTimeLabelFormat,\r\n numericSymbols = defaultOptions.lang.numericSymbols,\r\n i = numericSymbols && numericSymbols.length,\r\n multi,\r\n ret,\r\n formatOption = axis.options.labels.format,\r\n // make sure the same symbol is added for all labels on a linear axis\r\n numericSymbolDetector = axis.isLog ? value : axis.tickInterval;\r\n\r\n if (formatOption) {\r\n ret = format(formatOption, this);\r\n }\r\n else if (categories) {\r\n ret = value;\r\n }\r\n else if (dateTimeLabelFormat) {\r\n // datetime axis\r\n ret = dateFormat(dateTimeLabelFormat, value);\r\n }\r\n else if (i && numericSymbolDetector >= 1000) {\r\n // Decide whether we should add a numeric symbol like k (thousands) or M (millions).\r\n // If we are to enable this in tooltip or other places as well, we can move this\r\n // logic to the numberFormatter and enable it by a parameter.\r\n while (i-- && ret === UNDEFINED) {\r\n multi = Math.pow(1000, i + 1);\r\n if (numericSymbolDetector >= multi && numericSymbols[i] !== null) {\r\n ret = numberFormat(value / multi, -1) + numericSymbols[i];\r\n }\r\n }\r\n }\r\n\r\n if (ret === UNDEFINED) {\r\n if (value >= 1000) {\r\n // add thousands separators\r\n ret = numberFormat(value, 0);\r\n }\r\n else {\r\n // small numbers\r\n ret = numberFormat(value, -1);\r\n }\r\n }\r\n\r\n return ret;\r\n },\r\n\r\n /**\r\n * Get the minimum and maximum for the series of each axis\r\n */\r\n getSeriesExtremes: function() {\r\n var axis = this,\r\n chart = axis.chart;\r\n\r\n axis.hasVisibleSeries = false;\r\n\r\n // reset dataMin and dataMax in case we're redrawing\r\n axis.dataMin = axis.dataMax = null;\r\n\r\n // reset cached stacking extremes\r\n axis.stackExtremes = {};\r\n\r\n axis.buildStacks();\r\n\r\n // loop through this axis' series\r\n each(axis.series, function(series) {\r\n if (series.visible || !chart.options.chart.ignoreHiddenSeries) {\r\n var seriesOptions = series.options,\r\n xData,\r\n threshold = seriesOptions.threshold,\r\n seriesDataMin,\r\n seriesDataMax;\r\n\r\n axis.hasVisibleSeries = true;\r\n\r\n // Validate threshold in logarithmic axes\r\n if (axis.isLog && threshold <= 0) {\r\n threshold = null;\r\n }\r\n\r\n // Get dataMin and dataMax for X axes\r\n if (axis.isXAxis) {\r\n xData = series.xData;\r\n if (xData.length) {\r\n axis.dataMin = mathMin(\r\n pick(axis.dataMin, xData[0]),\r\n arrayMin(xData)\r\n );\r\n axis.dataMax = mathMax(\r\n pick(axis.dataMax, xData[0]),\r\n arrayMax(xData)\r\n );\r\n }\r\n\r\n // Get dataMin and dataMax for Y axes, as well as handle stacking and processed data\r\n }\r\n else {\r\n // Get this particular series extremes\r\n series.getExtremes();\r\n seriesDataMax = series.dataMax;\r\n seriesDataMin = series.dataMin;\r\n\r\n // Get the dataMin and dataMax so far. If percentage is used, the min and max are\r\n // always 0 and 100. If seriesDataMin and seriesDataMax is null, then series\r\n // doesn't have active y data, we continue with nulls\r\n if (defined(seriesDataMin) && defined(seriesDataMax)) {\r\n axis.dataMin = mathMin(\r\n pick(axis.dataMin, seriesDataMin),\r\n seriesDataMin\r\n );\r\n axis.dataMax = mathMax(\r\n pick(axis.dataMax, seriesDataMax),\r\n seriesDataMax\r\n );\r\n }\r\n\r\n // Adjust to threshold\r\n if (defined(threshold)) {\r\n if (axis.dataMin >= threshold) {\r\n axis.dataMin = threshold;\r\n axis.ignoreMinPadding = true;\r\n }\r\n else if (axis.dataMax < threshold) {\r\n axis.dataMax = threshold;\r\n axis.ignoreMaxPadding = true;\r\n }\r\n }\r\n }\r\n }\r\n });\r\n },\r\n\r\n /**\r\n * Translate from axis value to pixel position on the chart, or back\r\n *\r\n */\r\n translate: function(\r\n val,\r\n backwards,\r\n cvsCoord,\r\n old,\r\n handleLog,\r\n pointPlacement\r\n ) {\r\n var axis = this,\r\n axisLength = axis.len,\r\n sign = 1,\r\n cvsOffset = 0,\r\n localA = old ? axis.oldTransA : axis.transA,\r\n localMin = old ? axis.oldMin : axis.min,\r\n returnValue,\r\n minPixelPadding = axis.minPixelPadding,\r\n postTranslate =\r\n (axis.options.ordinal || (axis.isLog && handleLog)) && axis.lin2val;\r\n\r\n if (!localA) {\r\n localA = axis.transA;\r\n }\r\n\r\n // In vertical axes, the canvas coordinates start from 0 at the top like in\r\n // SVG.\r\n if (cvsCoord) {\r\n sign *= -1; // canvas coordinates inverts the value\r\n cvsOffset = axisLength;\r\n }\r\n\r\n // Handle reversed axis\r\n if (axis.reversed) {\r\n sign *= -1;\r\n cvsOffset -= sign * axisLength;\r\n }\r\n\r\n // From pixels to value\r\n if (backwards) {\r\n // reverse translation\r\n\r\n val = val * sign + cvsOffset;\r\n val -= minPixelPadding;\r\n returnValue = val / localA + localMin; // from chart pixel to value\r\n if (postTranslate) {\r\n // log and ordinal axes\r\n returnValue = axis.lin2val(returnValue);\r\n }\r\n\r\n // From value to pixels\r\n }\r\n else {\r\n if (postTranslate) {\r\n // log and ordinal axes\r\n val = axis.val2lin(val);\r\n }\r\n if (pointPlacement === \"between\") {\r\n pointPlacement = 0.5;\r\n }\r\n returnValue =\r\n sign * (val - localMin) * localA +\r\n cvsOffset +\r\n sign * minPixelPadding +\r\n (isNumber(pointPlacement)\r\n ? localA * pointPlacement * axis.pointRange\r\n : 0);\r\n }\r\n\r\n return returnValue;\r\n },\r\n\r\n /**\r\n * Utility method to translate an axis value to pixel position.\r\n * @param {Number} value A value in terms of axis units\r\n * @param {Boolean} paneCoordinates Whether to return the pixel coordinate relative to the chart\r\n * or just the axis/pane itself.\r\n */\r\n toPixels: function(value, paneCoordinates) {\r\n return (\r\n this.translate(value, false, !this.horiz, null, true) +\r\n (paneCoordinates ? 0 : this.pos)\r\n );\r\n },\r\n\r\n /*\r\n * Utility method to translate a pixel position in to an axis value\r\n * @param {Number} pixel The pixel value coordinate\r\n * @param {Boolean} paneCoordiantes Whether the input pixel is relative to the chart or just the\r\n * axis/pane itself.\r\n */\r\n toValue: function(pixel, paneCoordinates) {\r\n return this.translate(\r\n pixel - (paneCoordinates ? 0 : this.pos),\r\n true,\r\n !this.horiz,\r\n null,\r\n true\r\n );\r\n },\r\n\r\n /**\r\n * Create the path for a plot line that goes from the given value on\r\n * this axis, across the plot to the opposite side\r\n * @param {Number} value\r\n * @param {Number} lineWidth Used for calculation crisp line\r\n * @param {Number] old Use old coordinates (for resizing and rescaling)\r\n */\r\n getPlotLinePath: function(value, lineWidth, old, force) {\r\n var axis = this,\r\n chart = axis.chart,\r\n axisLeft = axis.left,\r\n axisTop = axis.top,\r\n x1,\r\n y1,\r\n x2,\r\n y2,\r\n translatedValue = axis.translate(value, null, null, old),\r\n cHeight = (old && chart.oldChartHeight) || chart.chartHeight,\r\n cWidth = (old && chart.oldChartWidth) || chart.chartWidth,\r\n skip,\r\n transB = axis.transB;\r\n\r\n x1 = x2 = mathRound(translatedValue + transB);\r\n y1 = y2 = mathRound(cHeight - translatedValue - transB);\r\n\r\n if (isNaN(translatedValue)) {\r\n // no min or max\r\n skip = true;\r\n }\r\n else if (axis.horiz) {\r\n y1 = axisTop;\r\n y2 = cHeight - axis.bottom;\r\n if (x1 < axisLeft || x1 > axisLeft + axis.width) {\r\n skip = true;\r\n }\r\n }\r\n else {\r\n x1 = axisLeft;\r\n x2 = cWidth - axis.right;\r\n\r\n if (y1 < axisTop || y1 > axisTop + axis.height) {\r\n skip = true;\r\n }\r\n }\r\n return skip && !force\r\n ? null\r\n : chart.renderer.crispLine([M, x1, y1, L, x2, y2], lineWidth || 0);\r\n },\r\n\r\n /**\r\n * Create the path for a plot band\r\n */\r\n getPlotBandPath: function(from, to) {\r\n var toPath = this.getPlotLinePath(to),\r\n path = this.getPlotLinePath(from);\r\n\r\n if (path && toPath) {\r\n path.push(toPath[4], toPath[5], toPath[1], toPath[2]);\r\n }\r\n else {\r\n // outside the axis area\r\n path = null;\r\n }\r\n\r\n return path;\r\n },\r\n\r\n /**\r\n * Set the tick positions of a linear axis to round values like whole tens or every five.\r\n */\r\n getLinearTickPositions: function(tickInterval, min, max) {\r\n var pos,\r\n lastPos,\r\n roundedMin = correctFloat(mathFloor(min / tickInterval) * tickInterval),\r\n roundedMax = correctFloat(mathCeil(max / tickInterval) * tickInterval),\r\n tickPositions = [];\r\n\r\n // Populate the intermediate values\r\n pos = roundedMin;\r\n while (pos <= roundedMax) {\r\n // Place the tick on the rounded value\r\n tickPositions.push(pos);\r\n\r\n // Always add the raw tickInterval, not the corrected one.\r\n pos = correctFloat(pos + tickInterval);\r\n\r\n // If the interval is not big enough in the current min - max range to actually increase\r\n // the loop variable, we need to break out to prevent endless loop. Issue #619\r\n if (pos === lastPos) {\r\n break;\r\n }\r\n\r\n // Record the last value\r\n lastPos = pos;\r\n }\r\n return tickPositions;\r\n },\r\n\r\n /**\r\n * Set the tick positions of a logarithmic axis\r\n */\r\n getLogTickPositions: function(interval, min, max, minor) {\r\n var axis = this,\r\n options = axis.options,\r\n axisLength = axis.len,\r\n // Since we use this method for both major and minor ticks,\r\n // use a local variable and return the result\r\n positions = [];\r\n\r\n // Reset\r\n if (!minor) {\r\n axis._minorAutoInterval = null;\r\n }\r\n\r\n // First case: All ticks fall on whole logarithms: 1, 10, 100 etc.\r\n if (interval >= 0.5) {\r\n interval = mathRound(interval);\r\n positions = axis.getLinearTickPositions(interval, min, max);\r\n\r\n // Second case: We need intermediary ticks. For example\r\n // 1, 2, 4, 6, 8, 10, 20, 40 etc.\r\n }\r\n else if (interval >= 0.08) {\r\n var roundedMin = mathFloor(min),\r\n intermediate,\r\n i,\r\n j,\r\n len,\r\n pos,\r\n lastPos,\r\n break2;\r\n\r\n if (interval > 0.3) {\r\n intermediate = [1, 2, 4];\r\n }\r\n else if (interval > 0.15) {\r\n // 0.2 equals five minor ticks per 1, 10, 100 etc\r\n intermediate = [1, 2, 4, 6, 8];\r\n }\r\n else {\r\n // 0.1 equals ten minor ticks per 1, 10, 100 etc\r\n intermediate = [1, 2, 3, 4, 5, 6, 7, 8, 9];\r\n }\r\n\r\n for (i = roundedMin; i < max + 1 && !break2; i++) {\r\n len = intermediate.length;\r\n for (j = 0; j < len && !break2; j++) {\r\n pos = log2lin(lin2log(i) * intermediate[j]);\r\n\r\n if (pos > min && (!minor || lastPos <= max)) {\r\n // #1670\r\n positions.push(lastPos);\r\n }\r\n\r\n if (lastPos > max) {\r\n break2 = true;\r\n }\r\n lastPos = pos;\r\n }\r\n }\r\n\r\n // Third case: We are so deep in between whole logarithmic values that\r\n // we might as well handle the tick positions like a linear axis. For\r\n // example 1.01, 1.02, 1.03, 1.04.\r\n }\r\n else {\r\n var realMin = lin2log(min),\r\n realMax = lin2log(max),\r\n tickIntervalOption =\r\n options[minor ? \"minorTickInterval\" : \"tickInterval\"],\r\n filteredTickIntervalOption =\r\n tickIntervalOption === \"auto\" ? null : tickIntervalOption,\r\n tickPixelIntervalOption = options.tickPixelInterval / (minor ? 5 : 1),\r\n totalPixelLength = minor\r\n ? axisLength / axis.tickPositions.length\r\n : axisLength;\r\n\r\n interval = pick(\r\n filteredTickIntervalOption,\r\n axis._minorAutoInterval,\r\n ((realMax - realMin) * tickPixelIntervalOption) /\r\n (totalPixelLength || 1)\r\n );\r\n\r\n interval = normalizeTickInterval(\r\n interval,\r\n null,\r\n getMagnitude(interval)\r\n );\r\n\r\n positions = map(\r\n axis.getLinearTickPositions(interval, realMin, realMax),\r\n log2lin\r\n );\r\n\r\n if (!minor) {\r\n axis._minorAutoInterval = interval / 5;\r\n }\r\n }\r\n\r\n // Set the axis-level tickInterval variable\r\n if (!minor) {\r\n axis.tickInterval = interval;\r\n }\r\n return positions;\r\n },\r\n\r\n /**\r\n * Return the minor tick positions. For logarithmic axes, reuse the same logic\r\n * as for major ticks.\r\n */\r\n getMinorTickPositions: function() {\r\n var axis = this,\r\n options = axis.options,\r\n tickPositions = axis.tickPositions,\r\n minorTickInterval = axis.minorTickInterval,\r\n minorTickPositions = [],\r\n pos,\r\n i,\r\n len;\r\n\r\n if (axis.isLog) {\r\n len = tickPositions.length;\r\n for (i = 1; i < len; i++) {\r\n minorTickPositions = minorTickPositions.concat(\r\n axis.getLogTickPositions(\r\n minorTickInterval,\r\n tickPositions[i - 1],\r\n tickPositions[i],\r\n true\r\n )\r\n );\r\n }\r\n }\r\n else if (axis.isDatetimeAxis && options.minorTickInterval === \"auto\") {\r\n // #1314\r\n minorTickPositions = minorTickPositions.concat(\r\n getTimeTicks(\r\n normalizeTimeTickInterval(minorTickInterval),\r\n axis.min,\r\n axis.max,\r\n options.startOfWeek\r\n )\r\n );\r\n if (minorTickPositions[0] < axis.min) {\r\n minorTickPositions.shift();\r\n }\r\n }\r\n else {\r\n for (\r\n pos = axis.min + ((tickPositions[0] - axis.min) % minorTickInterval);\r\n pos <= axis.max;\r\n pos += minorTickInterval\r\n ) {\r\n minorTickPositions.push(pos);\r\n }\r\n }\r\n return minorTickPositions;\r\n },\r\n\r\n /**\r\n * Adjust the min and max for the minimum range. Keep in mind that the series data is\r\n * not yet processed, so we don't have information on data cropping and grouping, or\r\n * updated axis.pointRange or series.pointRange. The data can't be processed until\r\n * we have finally established min and max.\r\n */\r\n adjustForMinRange: function() {\r\n var axis = this,\r\n options = axis.options,\r\n min = axis.min,\r\n max = axis.max,\r\n zoomOffset,\r\n spaceAvailable = axis.dataMax - axis.dataMin >= axis.minRange,\r\n closestDataRange,\r\n i,\r\n distance,\r\n xData,\r\n loopLength,\r\n minArgs,\r\n maxArgs;\r\n\r\n // Set the automatic minimum range based on the closest point distance\r\n if (axis.isXAxis && axis.minRange === UNDEFINED && !axis.isLog) {\r\n if (defined(options.min) || defined(options.max)) {\r\n axis.minRange = null; // don't do this again\r\n }\r\n else {\r\n // Find the closest distance between raw data points, as opposed to\r\n // closestPointRange that applies to processed points (cropped and grouped)\r\n each(axis.series, function(series) {\r\n xData = series.xData;\r\n loopLength = series.xIncrement ? 1 : xData.length - 1;\r\n for (i = loopLength; i > 0; i--) {\r\n distance = xData[i] - xData[i - 1];\r\n if (\r\n closestDataRange === UNDEFINED ||\r\n distance < closestDataRange\r\n ) {\r\n closestDataRange = distance;\r\n }\r\n }\r\n });\r\n axis.minRange = mathMin(\r\n closestDataRange * 5,\r\n axis.dataMax - axis.dataMin\r\n );\r\n }\r\n }\r\n\r\n // if minRange is exceeded, adjust\r\n if (max - min < axis.minRange) {\r\n var minRange = axis.minRange;\r\n zoomOffset = (minRange - max + min) / 2;\r\n\r\n // if min and max options have been set, don't go beyond it\r\n minArgs = [min - zoomOffset, pick(options.min, min - zoomOffset)];\r\n if (spaceAvailable) {\r\n // if space is available, stay within the data range\r\n minArgs[2] = axis.dataMin;\r\n }\r\n min = arrayMax(minArgs);\r\n\r\n maxArgs = [min + minRange, pick(options.max, min + minRange)];\r\n if (spaceAvailable) {\r\n // if space is availabe, stay within the data range\r\n maxArgs[2] = axis.dataMax;\r\n }\r\n\r\n max = arrayMin(maxArgs);\r\n\r\n // now if the max is adjusted, adjust the min back\r\n if (max - min < minRange) {\r\n minArgs[0] = max - minRange;\r\n minArgs[1] = pick(options.min, max - minRange);\r\n min = arrayMax(minArgs);\r\n }\r\n }\r\n\r\n // Record modified extremes\r\n axis.min = min;\r\n axis.max = max;\r\n },\r\n\r\n /**\r\n * Update translation information\r\n */\r\n setAxisTranslation: function(saveOld) {\r\n var axis = this,\r\n range = axis.max - axis.min,\r\n pointRange = 0,\r\n closestPointRange,\r\n minPointOffset = 0,\r\n pointRangePadding = 0,\r\n linkedParent = axis.linkedParent,\r\n ordinalCorrection,\r\n transA = axis.transA;\r\n\r\n // adjust translation for padding\r\n if (axis.isXAxis) {\r\n if (linkedParent) {\r\n minPointOffset = linkedParent.minPointOffset;\r\n pointRangePadding = linkedParent.pointRangePadding;\r\n }\r\n else {\r\n each(axis.series, function(series) {\r\n var seriesPointRange = series.pointRange,\r\n pointPlacement = series.options.pointPlacement,\r\n seriesClosestPointRange = series.closestPointRange;\r\n\r\n if (seriesPointRange > range) {\r\n // #1446\r\n seriesPointRange = 0;\r\n }\r\n pointRange = mathMax(pointRange, seriesPointRange);\r\n\r\n // minPointOffset is the value padding to the left of the axis in order to make\r\n // room for points with a pointRange, typically columns. When the pointPlacement option\r\n // is 'between' or 'on', this padding does not apply.\r\n minPointOffset = mathMax(\r\n minPointOffset,\r\n isString(pointPlacement) ? 0 : seriesPointRange / 2\r\n );\r\n\r\n // Determine the total padding needed to the length of the axis to make room for the\r\n // pointRange. If the series' pointPlacement is 'on', no padding is added.\r\n pointRangePadding = mathMax(\r\n pointRangePadding,\r\n pointPlacement === \"on\" ? 0 : seriesPointRange\r\n );\r\n\r\n // Set the closestPointRange\r\n if (!series.noSharedTooltip && defined(seriesClosestPointRange)) {\r\n closestPointRange = defined(closestPointRange)\r\n ? mathMin(closestPointRange, seriesClosestPointRange)\r\n : seriesClosestPointRange;\r\n }\r\n });\r\n }\r\n\r\n // Record minPointOffset and pointRangePadding\r\n ordinalCorrection =\r\n axis.ordinalSlope && closestPointRange\r\n ? axis.ordinalSlope / closestPointRange\r\n : 1; // #988, #1853\r\n axis.minPointOffset = minPointOffset =\r\n minPointOffset * ordinalCorrection;\r\n axis.pointRangePadding = pointRangePadding =\r\n pointRangePadding * ordinalCorrection;\r\n\r\n // pointRange means the width reserved for each point, like in a column chart\r\n axis.pointRange = mathMin(pointRange, range);\r\n\r\n // closestPointRange means the closest distance between points. In columns\r\n // it is mostly equal to pointRange, but in lines pointRange is 0 while closestPointRange\r\n // is some other value\r\n axis.closestPointRange = closestPointRange;\r\n }\r\n\r\n // Secondary values\r\n if (saveOld) {\r\n axis.oldTransA = transA;\r\n }\r\n axis.translationSlope = axis.transA = transA =\r\n axis.len / (range + pointRangePadding || 1);\r\n axis.transB = axis.horiz ? axis.left : axis.bottom; // translation addend\r\n axis.minPixelPadding = transA * minPointOffset;\r\n },\r\n\r\n /**\r\n * Set the tick positions to round values and optionally extend the extremes\r\n * to the nearest tick\r\n */\r\n setTickPositions: function(secondPass) {\r\n var axis = this,\r\n chart = axis.chart,\r\n options = axis.options,\r\n isLog = axis.isLog,\r\n isDatetimeAxis = axis.isDatetimeAxis,\r\n isXAxis = axis.isXAxis,\r\n isLinked = axis.isLinked,\r\n tickPositioner = axis.options.tickPositioner,\r\n maxPadding = options.maxPadding,\r\n minPadding = options.minPadding,\r\n length,\r\n linkedParentExtremes,\r\n tickIntervalOption = options.tickInterval,\r\n minTickIntervalOption = options.minTickInterval,\r\n tickPixelIntervalOption = options.tickPixelInterval,\r\n tickPositions,\r\n keepTwoTicksOnly,\r\n categories = axis.categories;\r\n\r\n // linked axis gets the extremes from the parent axis\r\n if (isLinked) {\r\n axis.linkedParent =\r\n chart[isXAxis ? \"xAxis\" : \"yAxis\"][options.linkedTo];\r\n linkedParentExtremes = axis.linkedParent.getExtremes();\r\n axis.min = pick(linkedParentExtremes.min, linkedParentExtremes.dataMin);\r\n axis.max = pick(linkedParentExtremes.max, linkedParentExtremes.dataMax);\r\n if (options.type !== axis.linkedParent.options.type) {\r\n error(11, 1); // Can't link axes of different type\r\n }\r\n }\r\n else {\r\n // initial min and max from the extreme data values\r\n axis.min = pick(axis.userMin, options.min, axis.dataMin);\r\n axis.max = pick(axis.userMax, options.max, axis.dataMax);\r\n }\r\n\r\n if (isLog) {\r\n if (\r\n !secondPass &&\r\n mathMin(axis.min, pick(axis.dataMin, axis.min)) <= 0\r\n ) {\r\n // #978\r\n error(10, 1); // Can't plot negative values on log axis\r\n }\r\n axis.min = correctFloat(log2lin(axis.min)); // correctFloat cures #934\r\n axis.max = correctFloat(log2lin(axis.max));\r\n }\r\n\r\n // handle zoomed range\r\n if (axis.range) {\r\n axis.userMin = axis.min = mathMax(axis.min, axis.max - axis.range); // #618\r\n axis.userMax = axis.max;\r\n if (secondPass) {\r\n axis.range = null; // don't use it when running setExtremes\r\n }\r\n }\r\n\r\n // Hook for adjusting this.min and this.max. Used by bubble series.\r\n if (axis.beforePadding) {\r\n axis.beforePadding();\r\n }\r\n\r\n // adjust min and max for the minimum range\r\n axis.adjustForMinRange();\r\n\r\n // Pad the values to get clear of the chart's edges. To avoid tickInterval taking the padding\r\n // into account, we do this after computing tick interval (#1337).\r\n if (\r\n !categories &&\r\n !axis.usePercentage &&\r\n !isLinked &&\r\n defined(axis.min) &&\r\n defined(axis.max)\r\n ) {\r\n length = axis.max - axis.min;\r\n if (length) {\r\n if (\r\n !defined(options.min) &&\r\n !defined(axis.userMin) &&\r\n minPadding &&\r\n (axis.dataMin < 0 || !axis.ignoreMinPadding)\r\n ) {\r\n axis.min -= length * minPadding;\r\n }\r\n if (\r\n !defined(options.max) &&\r\n !defined(axis.userMax) &&\r\n maxPadding &&\r\n (axis.dataMax > 0 || !axis.ignoreMaxPadding)\r\n ) {\r\n axis.max += length * maxPadding;\r\n }\r\n }\r\n }\r\n\r\n // get tickInterval\r\n if (\r\n axis.min === axis.max ||\r\n axis.min === undefined ||\r\n axis.max === undefined\r\n ) {\r\n axis.tickInterval = 1;\r\n }\r\n else if (\r\n isLinked &&\r\n !tickIntervalOption &&\r\n tickPixelIntervalOption === axis.linkedParent.options.tickPixelInterval\r\n ) {\r\n axis.tickInterval = axis.linkedParent.tickInterval;\r\n }\r\n else {\r\n axis.tickInterval = pick(\r\n tickIntervalOption,\r\n categories // for categoried axis, 1 is default, for linear axis use tickPix\r\n ? 1\r\n : // don't let it be more than the data range\r\n ((axis.max - axis.min) * tickPixelIntervalOption) /\r\n mathMax(axis.len, tickPixelIntervalOption)\r\n );\r\n // For squished axes, set only two ticks\r\n if (\r\n !defined(tickIntervalOption) &&\r\n axis.len < tickPixelIntervalOption &&\r\n !this.isRadial\r\n ) {\r\n keepTwoTicksOnly = true;\r\n axis.tickInterval /= 4; // tick extremes closer to the real values\r\n }\r\n }\r\n\r\n // Now we're finished detecting min and max, crop and group series data. This\r\n // is in turn needed in order to find tick positions in ordinal axes.\r\n if (isXAxis && !secondPass) {\r\n each(axis.series, function(series) {\r\n series.processData(\r\n axis.min !== axis.oldMin || axis.max !== axis.oldMax\r\n );\r\n });\r\n }\r\n\r\n // set the translation factor used in translate function\r\n axis.setAxisTranslation(true);\r\n\r\n // hook for ordinal axes and radial axes\r\n if (axis.beforeSetTickPositions) {\r\n axis.beforeSetTickPositions();\r\n }\r\n\r\n // hook for extensions, used in Highstock ordinal axes\r\n if (axis.postProcessTickInterval) {\r\n axis.tickInterval = axis.postProcessTickInterval(axis.tickInterval);\r\n }\r\n\r\n // In column-like charts, don't cramp in more ticks than there are points (#1943)\r\n if (axis.pointRange) {\r\n axis.tickInterval = mathMax(axis.pointRange, axis.tickInterval);\r\n }\r\n\r\n // Before normalizing the tick interval, handle minimum tick interval. This applies only if tickInterval is not defined.\r\n if (!tickIntervalOption && axis.tickInterval < minTickIntervalOption) {\r\n axis.tickInterval = minTickIntervalOption;\r\n }\r\n\r\n // for linear axes, get magnitude and normalize the interval\r\n if (!isDatetimeAxis && !isLog) {\r\n // linear\r\n if (!tickIntervalOption) {\r\n axis.tickInterval = normalizeTickInterval(\r\n axis.tickInterval,\r\n null,\r\n getMagnitude(axis.tickInterval),\r\n options\r\n );\r\n }\r\n }\r\n\r\n // get minorTickInterval\r\n axis.minorTickInterval =\r\n options.minorTickInterval === \"auto\" && axis.tickInterval\r\n ? axis.tickInterval / 5\r\n : options.minorTickInterval;\r\n\r\n // find the tick positions\r\n axis.tickPositions = tickPositions = options.tickPositions\r\n ? [].concat(options.tickPositions) // Work on a copy (#1565)\r\n : tickPositioner && tickPositioner.apply(axis, [axis.min, axis.max]);\r\n if (!tickPositions) {\r\n // Too many ticks\r\n if (\r\n !axis.ordinalPositions &&\r\n (axis.max - axis.min) / axis.tickInterval > mathMax(2 * axis.len, 200)\r\n ) {\r\n error(19, true);\r\n }\r\n\r\n if (isDatetimeAxis) {\r\n tickPositions = (axis.getNonLinearTimeTicks || getTimeTicks)(\r\n normalizeTimeTickInterval(axis.tickInterval, options.units),\r\n axis.min,\r\n axis.max,\r\n options.startOfWeek,\r\n axis.ordinalPositions,\r\n axis.closestPointRange,\r\n true\r\n );\r\n }\r\n else if (isLog) {\r\n tickPositions = axis.getLogTickPositions(\r\n axis.tickInterval,\r\n axis.min,\r\n axis.max\r\n );\r\n }\r\n else {\r\n tickPositions = axis.getLinearTickPositions(\r\n axis.tickInterval,\r\n axis.min,\r\n axis.max\r\n );\r\n }\r\n if (keepTwoTicksOnly) {\r\n tickPositions.splice(1, tickPositions.length - 2);\r\n }\r\n\r\n axis.tickPositions = tickPositions;\r\n }\r\n\r\n if (!isLinked) {\r\n // reset min/max or remove extremes based on start/end on tick\r\n var roundedMin = tickPositions[0],\r\n roundedMax = tickPositions[tickPositions.length - 1],\r\n minPointOffset = axis.minPointOffset || 0,\r\n singlePad;\r\n\r\n if (options.startOnTick) {\r\n axis.min = roundedMin;\r\n }\r\n else if (axis.min - minPointOffset > roundedMin) {\r\n tickPositions.shift();\r\n }\r\n\r\n if (options.endOnTick) {\r\n axis.max = roundedMax;\r\n }\r\n else if (axis.max + minPointOffset < roundedMax) {\r\n tickPositions.pop();\r\n }\r\n\r\n // When there is only one point, or all points have the same value on this axis, then min\r\n // and max are equal and tickPositions.length is 1. In this case, add some padding\r\n // in order to center the point, but leave it with one tick. #1337.\r\n if (tickPositions.length === 1) {\r\n singlePad = 0.001; // The lowest possible number to avoid extra padding on columns\r\n axis.min -= singlePad;\r\n axis.max += singlePad;\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Set the max ticks of either the x and y axis collection\r\n */\r\n setMaxTicks: function() {\r\n var chart = this.chart,\r\n maxTicks = chart.maxTicks || {},\r\n tickPositions = this.tickPositions,\r\n key = (this._maxTicksKey = [this.xOrY, this.pos, this.len].join(\"-\"));\r\n\r\n if (\r\n !this.isLinked &&\r\n !this.isDatetimeAxis &&\r\n tickPositions &&\r\n tickPositions.length > (maxTicks[key] || 0) &&\r\n this.options.alignTicks !== false\r\n ) {\r\n maxTicks[key] = tickPositions.length;\r\n }\r\n chart.maxTicks = maxTicks;\r\n },\r\n\r\n /**\r\n * When using multiple axes, adjust the number of ticks to match the highest\r\n * number of ticks in that group\r\n */\r\n adjustTickAmount: function() {\r\n var axis = this,\r\n chart = axis.chart,\r\n key = axis._maxTicksKey,\r\n tickPositions = axis.tickPositions,\r\n maxTicks = chart.maxTicks;\r\n\r\n if (\r\n maxTicks &&\r\n maxTicks[key] &&\r\n !axis.isDatetimeAxis &&\r\n !axis.categories &&\r\n !axis.isLinked &&\r\n axis.options.alignTicks !== false\r\n ) {\r\n // only apply to linear scale\r\n var oldTickAmount = axis.tickAmount,\r\n calculatedTickAmount = tickPositions.length,\r\n tickAmount;\r\n\r\n // set the axis-level tickAmount to use below\r\n axis.tickAmount = tickAmount = maxTicks[key];\r\n\r\n if (calculatedTickAmount < tickAmount) {\r\n while (tickPositions.length < tickAmount) {\r\n tickPositions.push(\r\n correctFloat(\r\n tickPositions[tickPositions.length - 1] + axis.tickInterval\r\n )\r\n );\r\n }\r\n axis.transA *= (calculatedTickAmount - 1) / (tickAmount - 1);\r\n axis.max = tickPositions[tickPositions.length - 1];\r\n }\r\n if (defined(oldTickAmount) && tickAmount !== oldTickAmount) {\r\n axis.isDirty = true;\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Set the scale based on data min and max, user set min and max or options\r\n *\r\n */\r\n setScale: function() {\r\n var axis = this,\r\n stacks = axis.stacks,\r\n type,\r\n i,\r\n isDirtyData,\r\n isDirtyAxisLength;\r\n\r\n axis.oldMin = axis.min;\r\n axis.oldMax = axis.max;\r\n axis.oldAxisLength = axis.len;\r\n\r\n // set the new axisLength\r\n axis.setAxisSize();\r\n //axisLength = horiz ? axisWidth : axisHeight;\r\n isDirtyAxisLength = axis.len !== axis.oldAxisLength;\r\n\r\n // is there new data?\r\n each(axis.series, function(series) {\r\n if (series.isDirtyData || series.isDirty || series.xAxis.isDirty) {\r\n // when x axis is dirty, we need new data extremes for y as well\r\n isDirtyData = true;\r\n }\r\n });\r\n\r\n // do we really need to go through all this?\r\n if (\r\n isDirtyAxisLength ||\r\n isDirtyData ||\r\n axis.isLinked ||\r\n axis.forceRedraw ||\r\n axis.userMin !== axis.oldUserMin ||\r\n axis.userMax !== axis.oldUserMax\r\n ) {\r\n // reset stacks\r\n if (!axis.isXAxis) {\r\n for (type in stacks) {\r\n for (i in stacks[type]) {\r\n stacks[type][i].total = null;\r\n stacks[type][i].cum = 0;\r\n }\r\n }\r\n }\r\n\r\n axis.forceRedraw = false;\r\n\r\n // get data extremes if needed\r\n axis.getSeriesExtremes();\r\n\r\n // get fixed positions based on tickInterval\r\n axis.setTickPositions();\r\n\r\n // record old values to decide whether a rescale is necessary later on (#540)\r\n axis.oldUserMin = axis.userMin;\r\n axis.oldUserMax = axis.userMax;\r\n\r\n // Mark as dirty if it is not already set to dirty and extremes have changed. #595.\r\n if (!axis.isDirty) {\r\n axis.isDirty =\r\n isDirtyAxisLength ||\r\n axis.min !== axis.oldMin ||\r\n axis.max !== axis.oldMax;\r\n }\r\n }\r\n else if (!axis.isXAxis) {\r\n if (axis.oldStacks) {\r\n stacks = axis.stacks = axis.oldStacks;\r\n }\r\n\r\n // reset stacks\r\n for (type in stacks) {\r\n for (i in stacks[type]) {\r\n stacks[type][i].cum = stacks[type][i].total;\r\n }\r\n }\r\n }\r\n\r\n // Set the maximum tick amount\r\n axis.setMaxTicks();\r\n },\r\n\r\n /**\r\n * Set the extremes and optionally redraw\r\n * @param {Number} newMin\r\n * @param {Number} newMax\r\n * @param {Boolean} redraw\r\n * @param {Boolean|Object} animation Whether to apply animation, and optionally animation\r\n * configuration\r\n * @param {Object} eventArguments\r\n *\r\n */\r\n setExtremes: function(newMin, newMax, redraw, animation, eventArguments) {\r\n var axis = this,\r\n chart = axis.chart;\r\n\r\n redraw = pick(redraw, true); // defaults to true\r\n\r\n // Extend the arguments with min and max\r\n eventArguments = extend(eventArguments, {\r\n min: newMin,\r\n max: newMax\r\n });\r\n\r\n // Fire the event\r\n fireEvent(axis, \"setExtremes\", eventArguments, function() {\r\n // the default event handler\r\n\r\n axis.userMin = newMin;\r\n axis.userMax = newMax;\r\n axis.eventArgs = eventArguments;\r\n\r\n // Mark for running afterSetExtremes\r\n axis.isDirtyExtremes = true;\r\n\r\n // redraw\r\n if (redraw) {\r\n chart.redraw(animation);\r\n }\r\n });\r\n },\r\n\r\n /**\r\n * Overridable method for zooming chart. Pulled out in a separate method to allow overriding\r\n * in stock charts.\r\n */\r\n zoom: function(newMin, newMax) {\r\n // Prevent pinch zooming out of range. Check for defined is for #1946.\r\n if (!this.allowZoomOutside) {\r\n if (defined(this.dataMin) && newMin <= this.dataMin) {\r\n newMin = UNDEFINED;\r\n }\r\n if (defined(this.dataMax) && newMax >= this.dataMax) {\r\n newMax = UNDEFINED;\r\n }\r\n }\r\n\r\n // In full view, displaying the reset zoom button is not required\r\n this.displayBtn = newMin !== UNDEFINED || newMax !== UNDEFINED;\r\n\r\n // Do it\r\n this.setExtremes(newMin, newMax, false, UNDEFINED, { trigger: \"zoom\" });\r\n return true;\r\n },\r\n\r\n /**\r\n * Update the axis metrics\r\n */\r\n setAxisSize: function() {\r\n var chart = this.chart,\r\n options = this.options,\r\n offsetLeft = options.offsetLeft || 0,\r\n offsetRight = options.offsetRight || 0,\r\n horiz = this.horiz,\r\n width,\r\n height,\r\n top,\r\n left;\r\n\r\n // Expose basic values to use in Series object and navigator\r\n this.left = left = pick(options.left, chart.plotLeft + offsetLeft);\r\n this.top = top = pick(options.top, chart.plotTop);\r\n this.width = width = pick(\r\n options.width,\r\n chart.plotWidth - offsetLeft + offsetRight\r\n );\r\n this.height = height = pick(options.height, chart.plotHeight);\r\n this.bottom = chart.chartHeight - height - top;\r\n this.right = chart.chartWidth - width - left;\r\n\r\n // Direction agnostic properties\r\n this.len = mathMax(horiz ? width : height, 0); // mathMax fixes #905\r\n this.pos = horiz ? left : top; // distance from SVG origin\r\n },\r\n\r\n /**\r\n * Get the actual axis extremes\r\n */\r\n getExtremes: function() {\r\n var axis = this,\r\n isLog = axis.isLog;\r\n\r\n return {\r\n min: isLog ? correctFloat(lin2log(axis.min)) : axis.min,\r\n max: isLog ? correctFloat(lin2log(axis.max)) : axis.max,\r\n dataMin: axis.dataMin,\r\n dataMax: axis.dataMax,\r\n userMin: axis.userMin,\r\n userMax: axis.userMax\r\n };\r\n },\r\n\r\n /**\r\n * Get the zero plane either based on zero or on the min or max value.\r\n * Used in bar and area plots\r\n */\r\n getThreshold: function(threshold) {\r\n var axis = this,\r\n isLog = axis.isLog;\r\n\r\n var realMin = isLog ? lin2log(axis.min) : axis.min,\r\n realMax = isLog ? lin2log(axis.max) : axis.max;\r\n\r\n if (realMin > threshold || threshold === null) {\r\n threshold = realMin;\r\n }\r\n else if (realMax < threshold) {\r\n threshold = realMax;\r\n }\r\n\r\n return axis.translate(threshold, 0, 1, 0, 1);\r\n },\r\n\r\n addPlotBand: function(options) {\r\n this.addPlotBandOrLine(options, \"plotBands\");\r\n },\r\n\r\n addPlotLine: function(options) {\r\n this.addPlotBandOrLine(options, \"plotLines\");\r\n },\r\n\r\n /**\r\n * Add a plot band or plot line after render time\r\n *\r\n * @param options {Object} The plotBand or plotLine configuration object\r\n */\r\n addPlotBandOrLine: function(options, coll) {\r\n var obj = new PlotLineOrBand(this, options).render(),\r\n userOptions = this.userOptions;\r\n\r\n if (obj) {\r\n // #2189\r\n // Add it to the user options for exporting and Axis.update\r\n if (coll) {\r\n userOptions[coll] = userOptions[coll] || [];\r\n userOptions[coll].push(options);\r\n }\r\n this.plotLinesAndBands.push(obj);\r\n }\r\n\r\n return obj;\r\n },\r\n\r\n /**\r\n * Compute auto alignment for the axis label based on which side the axis is on\r\n * and the given rotation for the label\r\n */\r\n autoLabelAlign: function(rotation) {\r\n var ret,\r\n angle = (pick(rotation, 0) - this.side * 90 + 720) % 360;\r\n\r\n if (angle > 15 && angle < 165) {\r\n ret = \"right\";\r\n }\r\n else if (angle > 195 && angle < 345) {\r\n ret = \"left\";\r\n }\r\n else {\r\n ret = \"center\";\r\n }\r\n return ret;\r\n },\r\n\r\n /**\r\n * Render the tick labels to a preliminary position to get their sizes\r\n */\r\n getOffset: function() {\r\n var axis = this,\r\n chart = axis.chart,\r\n renderer = chart.renderer,\r\n options = axis.options,\r\n tickPositions = axis.tickPositions,\r\n ticks = axis.ticks,\r\n horiz = axis.horiz,\r\n side = axis.side,\r\n invertedSide = chart.inverted ? [1, 0, 3, 2][side] : side,\r\n hasData,\r\n showAxis,\r\n titleOffset = 0,\r\n titleOffsetOption,\r\n titleMargin = 0,\r\n axisTitleOptions = options.title,\r\n labelOptions = options.labels,\r\n labelOffset = 0, // reset\r\n axisOffset = chart.axisOffset,\r\n clipOffset = chart.clipOffset,\r\n directionFactor = [-1, 1, 1, -1][side],\r\n n,\r\n i,\r\n autoStaggerLines = 1,\r\n maxStaggerLines = pick(labelOptions.maxStaggerLines, 5),\r\n sortedPositions,\r\n lastRight,\r\n overlap,\r\n pos,\r\n bBox,\r\n x,\r\n w,\r\n lineNo;\r\n\r\n // For reuse in Axis.render\r\n axis.hasData = hasData =\r\n axis.hasVisibleSeries ||\r\n (defined(axis.min) && defined(axis.max) && !!tickPositions);\r\n axis.showAxis = showAxis = hasData || pick(options.showEmpty, true);\r\n\r\n // Set/reset staggerLines\r\n axis.staggerLines = axis.horiz && labelOptions.staggerLines;\r\n\r\n // Create the axisGroup and gridGroup elements on first iteration\r\n if (!axis.axisGroup) {\r\n axis.gridGroup = renderer\r\n .g(\"grid\")\r\n .attr({ zIndex: options.gridZIndex || 1 })\r\n .add();\r\n axis.axisGroup = renderer\r\n .g(\"axis\")\r\n .attr({ zIndex: options.zIndex || 2 })\r\n .add();\r\n axis.labelGroup = renderer\r\n .g(\"axis-labels\")\r\n .attr({ zIndex: labelOptions.zIndex || 7 })\r\n .add();\r\n }\r\n\r\n if (hasData || axis.isLinked) {\r\n // Set the explicit or automatic label alignment\r\n axis.labelAlign = pick(\r\n labelOptions.align || axis.autoLabelAlign(labelOptions.rotation)\r\n );\r\n\r\n // Generate ticks\r\n each(tickPositions, function(pos) {\r\n if (!ticks[pos]) {\r\n ticks[pos] = new Tick(axis, pos);\r\n }\r\n else {\r\n ticks[pos].addLabel(); // update labels depending on tick interval\r\n }\r\n });\r\n\r\n // Handle automatic stagger lines\r\n if (\r\n axis.horiz &&\r\n !axis.staggerLines &&\r\n maxStaggerLines &&\r\n !labelOptions.rotation\r\n ) {\r\n sortedPositions = axis.reversed\r\n ? [].concat(tickPositions).reverse()\r\n : tickPositions;\r\n while (autoStaggerLines < maxStaggerLines) {\r\n lastRight = [];\r\n overlap = false;\r\n\r\n for (i = 0; i < sortedPositions.length; i++) {\r\n pos = sortedPositions[i];\r\n bBox = ticks[pos].label && ticks[pos].label.getBBox();\r\n w = bBox ? bBox.width : 0;\r\n lineNo = i % autoStaggerLines;\r\n\r\n if (w) {\r\n x = axis.translate(pos); // don't handle log\r\n if (lastRight[lineNo] !== UNDEFINED && x < lastRight[lineNo]) {\r\n overlap = true;\r\n }\r\n lastRight[lineNo] = x + w;\r\n }\r\n }\r\n if (overlap) {\r\n autoStaggerLines++;\r\n }\r\n else {\r\n break;\r\n }\r\n }\r\n\r\n if (autoStaggerLines > 1) {\r\n axis.staggerLines = autoStaggerLines;\r\n }\r\n }\r\n\r\n each(tickPositions, function(pos) {\r\n // left side must be align: right and right side must have align: left for labels\r\n if (\r\n side === 0 ||\r\n side === 2 ||\r\n { 1: \"left\", 3: \"right\" }[side] === axis.labelAlign\r\n ) {\r\n // get the highest offset\r\n labelOffset = mathMax(ticks[pos].getLabelSize(), labelOffset);\r\n }\r\n });\r\n if (axis.staggerLines) {\r\n labelOffset *= axis.staggerLines;\r\n axis.labelOffset = labelOffset;\r\n }\r\n }\r\n else {\r\n // doesn't have data\r\n for (n in ticks) {\r\n ticks[n].destroy();\r\n delete ticks[n];\r\n }\r\n }\r\n\r\n if (\r\n axisTitleOptions &&\r\n axisTitleOptions.text &&\r\n axisTitleOptions.enabled !== false\r\n ) {\r\n if (!axis.axisTitle) {\r\n axis.axisTitle = renderer\r\n .text(axisTitleOptions.text, 0, 0, axisTitleOptions.useHTML)\r\n .attr({\r\n zIndex: 7,\r\n rotation: axisTitleOptions.rotation || 0,\r\n align:\r\n axisTitleOptions.textAlign ||\r\n { low: \"left\", middle: \"center\", high: \"right\" }[\r\n axisTitleOptions.align\r\n ]\r\n })\r\n .css(axisTitleOptions.style)\r\n .add(axis.axisGroup);\r\n axis.axisTitle.isNew = true;\r\n }\r\n\r\n if (showAxis) {\r\n titleOffset = axis.axisTitle.getBBox()[horiz ? \"height\" : \"width\"];\r\n titleMargin = pick(axisTitleOptions.margin, horiz ? 5 : 10);\r\n titleOffsetOption = axisTitleOptions.offset;\r\n }\r\n\r\n // hide or show the title depending on whether showEmpty is set\r\n axis.axisTitle[showAxis ? \"show\" : \"hide\"]();\r\n }\r\n\r\n // handle automatic or user set offset\r\n axis.offset = directionFactor * pick(options.offset, axisOffset[side]);\r\n\r\n axis.axisTitleMargin = pick(\r\n titleOffsetOption,\r\n labelOffset +\r\n titleMargin +\r\n (side !== 2 &&\r\n labelOffset &&\r\n directionFactor * options.labels[horiz ? \"y\" : \"x\"])\r\n );\r\n\r\n axisOffset[side] = mathMax(\r\n axisOffset[side],\r\n axis.axisTitleMargin + titleOffset + directionFactor * axis.offset\r\n );\r\n clipOffset[invertedSide] = mathMax(\r\n clipOffset[invertedSide],\r\n mathFloor(options.lineWidth / 2) * 2\r\n );\r\n },\r\n\r\n /**\r\n * Get the path for the axis line\r\n */\r\n getLinePath: function(lineWidth) {\r\n var chart = this.chart,\r\n opposite = this.opposite,\r\n offset = this.offset,\r\n horiz = this.horiz,\r\n lineLeft = this.left + (opposite ? this.width : 0) + offset,\r\n lineTop =\r\n chart.chartHeight -\r\n this.bottom -\r\n (opposite ? this.height : 0) +\r\n offset;\r\n\r\n if (opposite) {\r\n lineWidth *= -1; // crispify the other way - #1480, #1687\r\n }\r\n\r\n return chart.renderer.crispLine(\r\n [\r\n M,\r\n horiz ? this.left : lineLeft,\r\n horiz ? lineTop : this.top,\r\n L,\r\n horiz ? chart.chartWidth - this.right : lineLeft,\r\n horiz ? lineTop : chart.chartHeight - this.bottom\r\n ],\r\n lineWidth\r\n );\r\n },\r\n\r\n /**\r\n * Position the title\r\n */\r\n getTitlePosition: function() {\r\n // compute anchor points for each of the title align options\r\n var horiz = this.horiz,\r\n axisLeft = this.left,\r\n axisTop = this.top,\r\n axisLength = this.len,\r\n axisTitleOptions = this.options.title,\r\n margin = horiz ? axisLeft : axisTop,\r\n opposite = this.opposite,\r\n offset = this.offset,\r\n fontSize = pInt(axisTitleOptions.style.fontSize || 12),\r\n // the position in the length direction of the axis\r\n alongAxis = {\r\n low: margin + (horiz ? 0 : axisLength),\r\n middle: margin + axisLength / 2,\r\n high: margin + (horiz ? axisLength : 0)\r\n }[axisTitleOptions.align],\r\n // the position in the perpendicular direction of the axis\r\n offAxis =\r\n (horiz ? axisTop + this.height : axisLeft) +\r\n (horiz ? 1 : -1) * // horizontal axis reverses the margin\r\n (opposite ? -1 : 1) * // so does opposite axes\r\n this.axisTitleMargin +\r\n (this.side === 2 ? fontSize : 0);\r\n\r\n return {\r\n x: horiz\r\n ? alongAxis\r\n : offAxis +\r\n (opposite ? this.width : 0) +\r\n offset +\r\n (axisTitleOptions.x || 0), // x\r\n y: horiz\r\n ? offAxis - (opposite ? this.height : 0) + offset\r\n : alongAxis + (axisTitleOptions.y || 0) // y\r\n };\r\n },\r\n\r\n /**\r\n * Render the axis\r\n */\r\n render: function() {\r\n var axis = this,\r\n chart = axis.chart,\r\n renderer = chart.renderer,\r\n options = axis.options,\r\n isLog = axis.isLog,\r\n isLinked = axis.isLinked,\r\n tickPositions = axis.tickPositions,\r\n axisTitle = axis.axisTitle,\r\n stacks = axis.stacks,\r\n ticks = axis.ticks,\r\n minorTicks = axis.minorTicks,\r\n alternateBands = axis.alternateBands,\r\n stackLabelOptions = options.stackLabels,\r\n alternateGridColor = options.alternateGridColor,\r\n tickmarkOffset = axis.tickmarkOffset,\r\n lineWidth = options.lineWidth,\r\n linePath,\r\n hasRendered = chart.hasRendered,\r\n slideInTicks =\r\n hasRendered && defined(axis.oldMin) && !isNaN(axis.oldMin),\r\n hasData = axis.hasData,\r\n showAxis = axis.showAxis,\r\n from,\r\n to;\r\n\r\n // Mark all elements inActive before we go over and mark the active ones\r\n each([ticks, minorTicks, alternateBands], function(coll) {\r\n var pos;\r\n for (pos in coll) {\r\n coll[pos].isActive = false;\r\n }\r\n });\r\n\r\n // If the series has data draw the ticks. Else only the line and title\r\n if (hasData || isLinked) {\r\n // minor ticks\r\n if (axis.minorTickInterval && !axis.categories) {\r\n each(axis.getMinorTickPositions(), function(pos) {\r\n if (!minorTicks[pos]) {\r\n minorTicks[pos] = new Tick(axis, pos, \"minor\");\r\n }\r\n\r\n // render new ticks in old position\r\n if (slideInTicks && minorTicks[pos].isNew) {\r\n minorTicks[pos].render(null, true);\r\n }\r\n\r\n minorTicks[pos].render(null, false, 1);\r\n });\r\n }\r\n\r\n // Major ticks. Pull out the first item and render it last so that\r\n // we can get the position of the neighbour label. #808.\r\n if (tickPositions.length) {\r\n // #1300\r\n each(tickPositions.slice(1).concat([tickPositions[0]]), function(\r\n pos,\r\n i\r\n ) {\r\n // Reorganize the indices\r\n i = i === tickPositions.length - 1 ? 0 : i + 1;\r\n\r\n // linked axes need an extra check to find out if\r\n if (!isLinked || (pos >= axis.min && pos <= axis.max)) {\r\n if (!ticks[pos]) {\r\n ticks[pos] = new Tick(axis, pos);\r\n }\r\n\r\n // render new ticks in old position\r\n if (slideInTicks && ticks[pos].isNew) {\r\n ticks[pos].render(i, true);\r\n }\r\n\r\n ticks[pos].render(i, false, 1);\r\n }\r\n });\r\n // In a categorized axis, the tick marks are displayed between labels. So\r\n // we need to add a tick mark and grid line at the left edge of the X axis.\r\n if (tickmarkOffset && axis.min === 0) {\r\n if (!ticks[-1]) {\r\n ticks[-1] = new Tick(axis, -1, null, true);\r\n }\r\n ticks[-1].render(-1);\r\n }\r\n }\r\n\r\n // alternate grid color\r\n if (alternateGridColor) {\r\n each(tickPositions, function(pos, i) {\r\n if (i % 2 === 0 && pos < axis.max) {\r\n if (!alternateBands[pos]) {\r\n alternateBands[pos] = new PlotLineOrBand(axis);\r\n }\r\n from = pos + tickmarkOffset; // #949\r\n to =\r\n tickPositions[i + 1] !== UNDEFINED\r\n ? tickPositions[i + 1] + tickmarkOffset\r\n : axis.max;\r\n alternateBands[pos].options = {\r\n from: isLog ? lin2log(from) : from,\r\n to: isLog ? lin2log(to) : to,\r\n color: alternateGridColor\r\n };\r\n alternateBands[pos].render();\r\n alternateBands[pos].isActive = true;\r\n }\r\n });\r\n }\r\n\r\n // custom plot lines and bands\r\n if (!axis._addedPlotLB) {\r\n // only first time\r\n each(\r\n (options.plotLines || []).concat(options.plotBands || []),\r\n function(plotLineOptions) {\r\n axis.addPlotBandOrLine(plotLineOptions);\r\n }\r\n );\r\n axis._addedPlotLB = true;\r\n }\r\n } // end if hasData\r\n\r\n // Remove inactive ticks\r\n each([ticks, minorTicks, alternateBands], function(coll) {\r\n var pos,\r\n i,\r\n forDestruction = [],\r\n delay = globalAnimation ? globalAnimation.duration || 500 : 0,\r\n destroyInactiveItems = function() {\r\n i = forDestruction.length;\r\n while (i--) {\r\n // When resizing rapidly, the same items may be destroyed in different timeouts,\r\n // or the may be reactivated\r\n if (\r\n coll[forDestruction[i]] &&\r\n !coll[forDestruction[i]].isActive\r\n ) {\r\n coll[forDestruction[i]].destroy();\r\n delete coll[forDestruction[i]];\r\n }\r\n }\r\n };\r\n\r\n for (pos in coll) {\r\n if (!coll[pos].isActive) {\r\n // Render to zero opacity\r\n coll[pos].render(pos, false, 0);\r\n coll[pos].isActive = false;\r\n forDestruction.push(pos);\r\n }\r\n }\r\n\r\n // When the objects are finished fading out, destroy them\r\n if (coll === alternateBands || !chart.hasRendered || !delay) {\r\n destroyInactiveItems();\r\n }\r\n else if (delay) {\r\n setTimeout(destroyInactiveItems, delay);\r\n }\r\n });\r\n\r\n // Static items. As the axis group is cleared on subsequent calls\r\n // to render, these items are added outside the group.\r\n // axis line\r\n if (lineWidth) {\r\n linePath = axis.getLinePath(lineWidth);\r\n if (!axis.axisLine) {\r\n axis.axisLine = renderer\r\n .path(linePath)\r\n .attr({\r\n stroke: options.lineColor,\r\n \"stroke-width\": lineWidth,\r\n zIndex: 7\r\n })\r\n .add(axis.axisGroup);\r\n }\r\n else {\r\n axis.axisLine.animate({ d: linePath });\r\n }\r\n\r\n // show or hide the line depending on options.showEmpty\r\n axis.axisLine[showAxis ? \"show\" : \"hide\"]();\r\n }\r\n\r\n if (axisTitle && showAxis) {\r\n axisTitle[axisTitle.isNew ? \"attr\" : \"animate\"](\r\n axis.getTitlePosition()\r\n );\r\n axisTitle.isNew = false;\r\n }\r\n\r\n // Stacked totals:\r\n if (stackLabelOptions && stackLabelOptions.enabled) {\r\n var stackKey,\r\n oneStack,\r\n stackCategory,\r\n stackTotalGroup = axis.stackTotalGroup;\r\n\r\n // Create a separate group for the stack total labels\r\n if (!stackTotalGroup) {\r\n axis.stackTotalGroup = stackTotalGroup = renderer\r\n .g(\"stack-labels\")\r\n .attr({\r\n visibility: VISIBLE,\r\n zIndex: 6\r\n })\r\n .add();\r\n }\r\n\r\n // plotLeft/Top will change when y axis gets wider so we need to translate the\r\n // stackTotalGroup at every render call. See bug #506 and #516\r\n stackTotalGroup.translate(chart.plotLeft, chart.plotTop);\r\n\r\n // Render each stack total\r\n for (stackKey in stacks) {\r\n oneStack = stacks[stackKey];\r\n for (stackCategory in oneStack) {\r\n oneStack[stackCategory].render(stackTotalGroup);\r\n }\r\n }\r\n }\r\n // End stacked totals\r\n\r\n axis.isDirty = false;\r\n },\r\n\r\n /**\r\n * Remove a plot band or plot line from the chart by id\r\n * @param {Object} id\r\n */\r\n removePlotBandOrLine: function(id) {\r\n var plotLinesAndBands = this.plotLinesAndBands,\r\n options = this.options,\r\n userOptions = this.userOptions,\r\n i = plotLinesAndBands.length;\r\n while (i--) {\r\n if (plotLinesAndBands[i].id === id) {\r\n plotLinesAndBands[i].destroy();\r\n }\r\n }\r\n each(\r\n [\r\n options.plotLines || [],\r\n userOptions.plotLines || [],\r\n options.plotBands || [],\r\n userOptions.plotBands || []\r\n ],\r\n function(arr) {\r\n i = arr.length;\r\n while (i--) {\r\n if (arr[i].id === id) {\r\n erase(arr, arr[i]);\r\n }\r\n }\r\n }\r\n );\r\n },\r\n\r\n /**\r\n * Update the axis title by options\r\n */\r\n setTitle: function(newTitleOptions, redraw) {\r\n this.update({ title: newTitleOptions }, redraw);\r\n },\r\n\r\n /**\r\n * Redraw the axis to reflect changes in the data or axis extremes\r\n */\r\n redraw: function() {\r\n var axis = this,\r\n chart = axis.chart,\r\n pointer = chart.pointer;\r\n\r\n // hide tooltip and hover states\r\n if (pointer.reset) {\r\n pointer.reset(true);\r\n }\r\n\r\n // render the axis\r\n axis.render();\r\n\r\n // move plot lines and bands\r\n each(axis.plotLinesAndBands, function(plotLine) {\r\n plotLine.render();\r\n });\r\n\r\n // mark associated series as dirty and ready for redraw\r\n each(axis.series, function(series) {\r\n series.isDirty = true;\r\n });\r\n },\r\n\r\n /**\r\n * Build the stacks from top down\r\n */\r\n buildStacks: function() {\r\n var series = this.series,\r\n i = series.length;\r\n if (!this.isXAxis) {\r\n while (i--) {\r\n series[i].setStackedPoints();\r\n }\r\n // Loop up again to compute percent stack\r\n if (this.usePercentage) {\r\n for (i = 0; i < series.length; i++) {\r\n series[i].setPercentStacks();\r\n }\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Set new axis categories and optionally redraw\r\n * @param {Array} categories\r\n * @param {Boolean} redraw\r\n */\r\n setCategories: function(categories, redraw) {\r\n this.update({ categories: categories }, redraw);\r\n },\r\n\r\n /**\r\n * Destroys an Axis instance.\r\n */\r\n destroy: function(keepEvents) {\r\n var axis = this,\r\n stacks = axis.stacks,\r\n stackKey,\r\n plotLinesAndBands = axis.plotLinesAndBands,\r\n i;\r\n\r\n // Remove the events\r\n if (!keepEvents) {\r\n removeEvent(axis);\r\n }\r\n\r\n // Destroy each stack total\r\n for (stackKey in stacks) {\r\n destroyObjectProperties(stacks[stackKey]);\r\n\r\n stacks[stackKey] = null;\r\n }\r\n\r\n // Destroy collections\r\n each([axis.ticks, axis.minorTicks, axis.alternateBands], function(coll) {\r\n destroyObjectProperties(coll);\r\n });\r\n i = plotLinesAndBands.length;\r\n while (i--) {\r\n // #1975\r\n plotLinesAndBands[i].destroy();\r\n }\r\n\r\n // Destroy local variables\r\n each(\r\n [\r\n \"stackTotalGroup\",\r\n \"axisLine\",\r\n \"axisGroup\",\r\n \"gridGroup\",\r\n \"labelGroup\",\r\n \"axisTitle\"\r\n ],\r\n function(prop) {\r\n if (axis[prop]) {\r\n axis[prop] = axis[prop].destroy();\r\n }\r\n }\r\n );\r\n }\r\n }; // end Axis\r\n\r\n /**\r\n * The tooltip object\r\n * @param {Object} chart The chart instance\r\n * @param {Object} options Tooltip options\r\n */\r\n function Tooltip() {\r\n this.init.apply(this, arguments);\r\n }\r\n\r\n Tooltip.prototype = {\r\n init: function(chart, options) {\r\n var borderWidth = options.borderWidth,\r\n style = options.style,\r\n padding = pInt(style.padding);\r\n\r\n // Save the chart and options\r\n this.chart = chart;\r\n this.options = options;\r\n\r\n // Keep track of the current series\r\n //this.currentSeries = UNDEFINED;\r\n\r\n // List of crosshairs\r\n this.crosshairs = [];\r\n\r\n // Current values of x and y when animating\r\n this.now = { x: 0, y: 0 };\r\n\r\n // The tooltip is initially hidden\r\n this.isHidden = true;\r\n\r\n // create the label\r\n this.label = chart.renderer\r\n .label(\r\n \"\",\r\n 0,\r\n 0,\r\n options.shape,\r\n null,\r\n null,\r\n options.useHTML,\r\n null,\r\n \"tooltip\"\r\n )\r\n .attr({\r\n padding: padding,\r\n fill: options.backgroundColor,\r\n \"stroke-width\": borderWidth,\r\n r: options.borderRadius,\r\n zIndex: 8\r\n })\r\n .css(style)\r\n .css({ padding: 0 }) // Remove it from VML, the padding is applied as an attribute instead (#1117)\r\n .add()\r\n .attr({ y: -999 }); // #2301\r\n\r\n // When using canVG the shadow shows up as a gray circle\r\n // even if the tooltip is hidden.\r\n if (!useCanVG) {\r\n this.label.shadow(options.shadow);\r\n }\r\n\r\n // Public property for getting the shared state.\r\n this.shared = options.shared;\r\n },\r\n\r\n /**\r\n * Destroy the tooltip and its elements.\r\n */\r\n destroy: function() {\r\n each(this.crosshairs, function(crosshair) {\r\n if (crosshair) {\r\n crosshair.destroy();\r\n }\r\n });\r\n\r\n // Destroy and clear local variables\r\n if (this.label) {\r\n this.label = this.label.destroy();\r\n }\r\n clearTimeout(this.hideTimer);\r\n clearTimeout(this.tooltipTimeout);\r\n },\r\n\r\n /**\r\n * Provide a soft movement for the tooltip\r\n *\r\n * @param {Number} x\r\n * @param {Number} y\r\n * @private\r\n */\r\n move: function(x, y, anchorX, anchorY) {\r\n var tooltip = this,\r\n now = tooltip.now,\r\n animate = tooltip.options.animation !== false && !tooltip.isHidden;\r\n\r\n // get intermediate values for animation\r\n extend(now, {\r\n x: animate ? (2 * now.x + x) / 3 : x,\r\n y: animate ? (now.y + y) / 2 : y,\r\n anchorX: animate ? (2 * now.anchorX + anchorX) / 3 : anchorX,\r\n anchorY: animate ? (now.anchorY + anchorY) / 2 : anchorY\r\n });\r\n\r\n // move to the intermediate value\r\n tooltip.label.attr(now);\r\n\r\n // run on next tick of the mouse tracker\r\n if (animate && (mathAbs(x - now.x) > 1 || mathAbs(y - now.y) > 1)) {\r\n // never allow two timeouts\r\n clearTimeout(this.tooltipTimeout);\r\n\r\n // set the fixed interval ticking for the smooth tooltip\r\n this.tooltipTimeout = setTimeout(function() {\r\n // The interval function may still be running during destroy, so check that the chart is really there before calling.\r\n if (tooltip) {\r\n tooltip.move(x, y, anchorX, anchorY);\r\n }\r\n }, 32);\r\n }\r\n },\r\n\r\n /**\r\n * Hide the tooltip\r\n */\r\n hide: function() {\r\n var tooltip = this,\r\n hoverPoints;\r\n\r\n clearTimeout(this.hideTimer); // disallow duplicate timers (#1728, #1766)\r\n if (!this.isHidden) {\r\n hoverPoints = this.chart.hoverPoints;\r\n\r\n this.hideTimer = setTimeout(function() {\r\n tooltip.label.fadeOut();\r\n tooltip.isHidden = true;\r\n }, pick(this.options.hideDelay, 500));\r\n\r\n // hide previous hoverPoints and set new\r\n if (hoverPoints) {\r\n each(hoverPoints, function(point) {\r\n point.setState();\r\n });\r\n }\r\n\r\n this.chart.hoverPoints = null;\r\n }\r\n },\r\n\r\n /**\r\n * Hide the crosshairs\r\n */\r\n hideCrosshairs: function() {\r\n each(this.crosshairs, function(crosshair) {\r\n if (crosshair) {\r\n crosshair.hide();\r\n }\r\n });\r\n },\r\n\r\n /**\r\n * Extendable method to get the anchor position of the tooltip\r\n * from a point or set of points\r\n */\r\n getAnchor: function(points, mouseEvent) {\r\n var ret,\r\n chart = this.chart,\r\n inverted = chart.inverted,\r\n plotTop = chart.plotTop,\r\n plotX = 0,\r\n plotY = 0,\r\n yAxis;\r\n\r\n points = splat(points);\r\n\r\n // Pie uses a special tooltipPos\r\n ret = points[0].tooltipPos;\r\n\r\n // When tooltip follows mouse, relate the position to the mouse\r\n if (this.followPointer && mouseEvent) {\r\n if (mouseEvent.chartX === UNDEFINED) {\r\n mouseEvent = chart.pointer.normalize(mouseEvent);\r\n }\r\n ret = [mouseEvent.chartX - chart.plotLeft, mouseEvent.chartY - plotTop];\r\n }\r\n // When shared, use the average position\r\n if (!ret) {\r\n each(points, function(point) {\r\n yAxis = point.series.yAxis;\r\n plotX += point.plotX;\r\n plotY +=\r\n (point.plotLow\r\n ? (point.plotLow + point.plotHigh) / 2\r\n : point.plotY) + (!inverted && yAxis ? yAxis.top - plotTop : 0); // #1151\r\n });\r\n\r\n plotX /= points.length;\r\n plotY /= points.length;\r\n\r\n ret = [\r\n inverted ? chart.plotWidth - plotY : plotX,\r\n this.shared && !inverted && points.length > 1 && mouseEvent\r\n ? mouseEvent.chartY - plotTop // place shared tooltip next to the mouse (#424)\r\n : inverted\r\n ? chart.plotHeight - plotX\r\n : plotY\r\n ];\r\n }\r\n\r\n return map(ret, mathRound);\r\n },\r\n\r\n /**\r\n * Place the tooltip in a chart without spilling over\r\n * and not covering the point it self.\r\n */\r\n getPosition: function(boxWidth, boxHeight, point) {\r\n // Set up the variables\r\n var chart = this.chart,\r\n plotLeft = chart.plotLeft,\r\n plotTop = chart.plotTop,\r\n plotWidth = chart.plotWidth,\r\n plotHeight = chart.plotHeight,\r\n distance = pick(this.options.distance, 12),\r\n pointX = point.plotX,\r\n pointY = point.plotY,\r\n x =\r\n pointX +\r\n plotLeft +\r\n (chart.inverted ? distance : -boxWidth - distance),\r\n y = pointY - boxHeight + plotTop + 15, // 15 means the point is 15 pixels up from the bottom of the tooltip\r\n alignedRight;\r\n\r\n // It is too far to the left, adjust it\r\n if (x < 7) {\r\n x = plotLeft + mathMax(pointX, 0) + distance;\r\n }\r\n\r\n // Test to see if the tooltip is too far to the right,\r\n // if it is, move it back to be inside and then up to not cover the point.\r\n if (x + boxWidth > plotLeft + plotWidth) {\r\n x -= x + boxWidth - (plotLeft + plotWidth);\r\n y = pointY - boxHeight + plotTop - distance;\r\n alignedRight = true;\r\n }\r\n\r\n // If it is now above the plot area, align it to the top of the plot area\r\n if (y < plotTop + 5) {\r\n y = plotTop + 5;\r\n\r\n // If the tooltip is still covering the point, move it below instead\r\n if (alignedRight && pointY >= y && pointY <= y + boxHeight) {\r\n y = pointY + plotTop + distance; // below\r\n }\r\n }\r\n\r\n // Now if the tooltip is below the chart, move it up. It's better to cover the\r\n // point than to disappear outside the chart. #834.\r\n if (y + boxHeight > plotTop + plotHeight) {\r\n y = mathMax(plotTop, plotTop + plotHeight - boxHeight - distance); // below\r\n }\r\n\r\n return { x: x, y: y };\r\n },\r\n\r\n /**\r\n * In case no user defined formatter is given, this will be used. Note that the context\r\n * here is an object holding point, series, x, y etc.\r\n */\r\n defaultFormatter: function(tooltip) {\r\n var items = this.points || splat(this),\r\n series = items[0].series,\r\n s;\r\n\r\n // build the header\r\n s = [series.tooltipHeaderFormatter(items[0])];\r\n\r\n // build the values\r\n each(items, function(item) {\r\n series = item.series;\r\n s.push(\r\n (series.tooltipFormatter && series.tooltipFormatter(item)) ||\r\n item.point.tooltipFormatter(series.tooltipOptions.pointFormat)\r\n );\r\n });\r\n\r\n // footer\r\n s.push(tooltip.options.footerFormat || \"\");\r\n\r\n return s.join(\"\");\r\n },\r\n\r\n /**\r\n * Refresh the tooltip's text and position.\r\n * @param {Object} point\r\n */\r\n refresh: function(point, mouseEvent) {\r\n var tooltip = this,\r\n chart = tooltip.chart,\r\n label = tooltip.label,\r\n options = tooltip.options,\r\n x,\r\n y,\r\n anchor,\r\n textConfig = {},\r\n text,\r\n pointConfig = [],\r\n formatter = options.formatter || tooltip.defaultFormatter,\r\n hoverPoints = chart.hoverPoints,\r\n borderColor,\r\n crosshairsOptions = options.crosshairs,\r\n shared = tooltip.shared,\r\n currentSeries;\r\n\r\n clearTimeout(this.hideTimer);\r\n\r\n // get the reference point coordinates (pie charts use tooltipPos)\r\n tooltip.followPointer = splat(\r\n point\r\n )[0].series.tooltipOptions.followPointer;\r\n anchor = tooltip.getAnchor(point, mouseEvent);\r\n x = anchor[0];\r\n y = anchor[1];\r\n\r\n // shared tooltip, array is sent over\r\n if (shared && !(point.series && point.series.noSharedTooltip)) {\r\n // hide previous hoverPoints and set new\r\n\r\n chart.hoverPoints = point;\r\n if (hoverPoints) {\r\n each(hoverPoints, function(point) {\r\n point.setState();\r\n });\r\n }\r\n\r\n each(point, function(item) {\r\n item.setState(HOVER_STATE);\r\n\r\n pointConfig.push(item.getLabelConfig());\r\n });\r\n\r\n textConfig = {\r\n x: point[0].category,\r\n y: point[0].y\r\n };\r\n textConfig.points = pointConfig;\r\n point = point[0];\r\n\r\n // single point tooltip\r\n }\r\n else {\r\n textConfig = point.getLabelConfig();\r\n }\r\n text = formatter.call(textConfig, tooltip);\r\n\r\n // register the current series\r\n currentSeries = point.series;\r\n\r\n // update the inner HTML\r\n if (text === false) {\r\n this.hide();\r\n }\r\n else {\r\n // show it\r\n if (tooltip.isHidden) {\r\n stop(label);\r\n label.attr(\"opacity\", 1).show();\r\n }\r\n\r\n // update text\r\n label.attr({\r\n text: text\r\n });\r\n\r\n // set the stroke color of the box\r\n borderColor =\r\n options.borderColor ||\r\n point.color ||\r\n currentSeries.color ||\r\n \"#606060\";\r\n label.attr({\r\n stroke: borderColor\r\n });\r\n\r\n tooltip.updatePosition({ plotX: x, plotY: y });\r\n\r\n this.isHidden = false;\r\n }\r\n\r\n // crosshairs\r\n if (crosshairsOptions) {\r\n crosshairsOptions = splat(crosshairsOptions); // [x, y]\r\n\r\n var path,\r\n i = crosshairsOptions.length,\r\n attribs,\r\n axis,\r\n val,\r\n series;\r\n\r\n while (i--) {\r\n series = point.series;\r\n axis = series[i ? \"yAxis\" : \"xAxis\"];\r\n if (crosshairsOptions[i] && axis) {\r\n val = i ? pick(point.stackY, point.y) : point.x; // #814\r\n if (axis.isLog) {\r\n // #1671\r\n val = log2lin(val);\r\n }\r\n if (i === 1 && series.modifyValue) {\r\n // #1205, #2316\r\n val = series.modifyValue(val);\r\n }\r\n\r\n path = axis.getPlotLinePath(val, 1);\r\n\r\n if (tooltip.crosshairs[i]) {\r\n tooltip.crosshairs[i].attr({ d: path, visibility: VISIBLE });\r\n }\r\n else {\r\n attribs = {\r\n \"stroke-width\": crosshairsOptions[i].width || 1,\r\n stroke: crosshairsOptions[i].color || \"#C0C0C0\",\r\n zIndex: crosshairsOptions[i].zIndex || 2\r\n };\r\n if (crosshairsOptions[i].dashStyle) {\r\n attribs.dashstyle = crosshairsOptions[i].dashStyle;\r\n }\r\n tooltip.crosshairs[i] = chart.renderer\r\n .path(path)\r\n .attr(attribs)\r\n .add();\r\n }\r\n }\r\n }\r\n }\r\n fireEvent(chart, \"tooltipRefresh\", {\r\n text: text,\r\n x: x + chart.plotLeft,\r\n y: y + chart.plotTop,\r\n borderColor: borderColor\r\n });\r\n },\r\n\r\n /**\r\n * Find the new position and perform the move\r\n */\r\n updatePosition: function(point) {\r\n var chart = this.chart,\r\n label = this.label,\r\n pos = (this.options.positioner || this.getPosition).call(\r\n this,\r\n label.width,\r\n label.height,\r\n point\r\n );\r\n\r\n // do the move\r\n this.move(\r\n mathRound(pos.x),\r\n mathRound(pos.y),\r\n point.plotX + chart.plotLeft,\r\n point.plotY + chart.plotTop\r\n );\r\n }\r\n };\r\n /**\r\n * The mouse tracker object. All methods starting with \"on\" are primary DOM event handlers.\r\n * Subsequent methods should be named differently from what they are doing.\r\n * @param {Object} chart The Chart instance\r\n * @param {Object} options The root options object\r\n */\r\n function Pointer(chart, options) {\r\n this.init(chart, options);\r\n }\r\n\r\n Pointer.prototype = {\r\n /**\r\n * Initialize Pointer\r\n */\r\n init: function(chart, options) {\r\n var chartOptions = options.chart,\r\n chartEvents = chartOptions.events,\r\n zoomType = useCanVG ? \"\" : chartOptions.zoomType,\r\n inverted = chart.inverted,\r\n zoomX,\r\n zoomY;\r\n\r\n // Store references\r\n this.options = options;\r\n this.chart = chart;\r\n\r\n // Zoom status\r\n this.zoomX = zoomX = /x/.test(zoomType);\r\n this.zoomY = zoomY = /y/.test(zoomType);\r\n this.zoomHor = (zoomX && !inverted) || (zoomY && inverted);\r\n this.zoomVert = (zoomY && !inverted) || (zoomX && inverted);\r\n\r\n // Do we need to handle click on a touch device?\r\n this.runChartClick = chartEvents && !!chartEvents.click;\r\n\r\n this.pinchDown = [];\r\n this.lastValidTouch = {};\r\n\r\n if (options.tooltip.enabled) {\r\n chart.tooltip = new Tooltip(chart, options.tooltip);\r\n }\r\n\r\n this.setDOMEvents();\r\n },\r\n\r\n /**\r\n * Add crossbrowser support for chartX and chartY\r\n * @param {Object} e The event object in standard browsers\r\n */\r\n normalize: function(e, chartPosition) {\r\n var chartX, chartY, ePos;\r\n\r\n // common IE normalizing\r\n e = e || win.event;\r\n if (!e.target) {\r\n e.target = e.srcElement;\r\n }\r\n\r\n // Framework specific normalizing (#1165)\r\n e = washMouseEvent(e);\r\n\r\n // iOS\r\n ePos = e.touches ? e.touches.item(0) : e;\r\n\r\n // Get mouse position\r\n if (!chartPosition) {\r\n this.chartPosition = chartPosition = offset(this.chart.container);\r\n }\r\n\r\n // chartX and chartY\r\n if (ePos.pageX === UNDEFINED) {\r\n // IE < 9. #886.\r\n chartX = mathMax(e.x, e.clientX - chartPosition.left); // #2005, #2129: the second case is\r\n // for IE10 quirks mode within framesets\r\n chartY = e.y;\r\n }\r\n else {\r\n chartX = ePos.pageX - chartPosition.left;\r\n chartY = ePos.pageY - chartPosition.top;\r\n }\r\n\r\n return extend(e, {\r\n chartX: mathRound(chartX),\r\n chartY: mathRound(chartY)\r\n });\r\n },\r\n\r\n /**\r\n * Get the click position in terms of axis values.\r\n *\r\n * @param {Object} e A pointer event\r\n */\r\n getCoordinates: function(e) {\r\n var coordinates = {\r\n xAxis: [],\r\n yAxis: []\r\n };\r\n\r\n each(this.chart.axes, function(axis) {\r\n coordinates[axis.isXAxis ? \"xAxis\" : \"yAxis\"].push({\r\n axis: axis,\r\n value: axis.toValue(e[axis.horiz ? \"chartX\" : \"chartY\"])\r\n });\r\n });\r\n return coordinates;\r\n },\r\n\r\n /**\r\n * Return the index in the tooltipPoints array, corresponding to pixel position in\r\n * the plot area.\r\n */\r\n getIndex: function(e) {\r\n var chart = this.chart;\r\n return chart.inverted\r\n ? chart.plotHeight + chart.plotTop - e.chartY\r\n : e.chartX - chart.plotLeft;\r\n },\r\n\r\n /**\r\n * With line type charts with a single tracker, get the point closest to the mouse.\r\n * Run Point.onMouseOver and display tooltip for the point or points.\r\n */\r\n runPointActions: function(e) {\r\n var pointer = this,\r\n chart = pointer.chart,\r\n series = chart.series,\r\n tooltip = chart.tooltip,\r\n point,\r\n points,\r\n hoverPoint = chart.hoverPoint,\r\n hoverSeries = chart.hoverSeries,\r\n i,\r\n j,\r\n distance = chart.chartWidth,\r\n index = pointer.getIndex(e),\r\n anchor;\r\n\r\n // shared tooltip\r\n if (\r\n tooltip &&\r\n pointer.options.tooltip.shared &&\r\n !(hoverSeries && hoverSeries.noSharedTooltip)\r\n ) {\r\n points = [];\r\n\r\n // loop over all series and find the ones with points closest to the mouse\r\n i = series.length;\r\n for (j = 0; j < i; j++) {\r\n if (\r\n series[j].visible &&\r\n series[j].options.enableMouseTracking !== false &&\r\n !series[j].noSharedTooltip &&\r\n series[j].tooltipPoints.length\r\n ) {\r\n point = series[j].tooltipPoints[index];\r\n if (point && point.series) {\r\n // not a dummy point, #1544\r\n point._dist = mathAbs(index - point.clientX);\r\n distance = mathMin(distance, point._dist);\r\n points.push(point);\r\n }\r\n }\r\n }\r\n // remove furthest points\r\n i = points.length;\r\n while (i--) {\r\n if (points[i]._dist > distance) {\r\n points.splice(i, 1);\r\n }\r\n }\r\n // refresh the tooltip if necessary\r\n if (points.length && points[0].clientX !== pointer.hoverX) {\r\n tooltip.refresh(points, e);\r\n pointer.hoverX = points[0].clientX;\r\n }\r\n }\r\n\r\n // separate tooltip and general mouse events\r\n if (hoverSeries && hoverSeries.tracker) {\r\n // only use for line-type series with common tracker\r\n\r\n // get the point\r\n point = hoverSeries.tooltipPoints[index];\r\n\r\n // a new point is hovered, refresh the tooltip\r\n if (point && point !== hoverPoint) {\r\n // trigger the events\r\n point.onMouseOver(e);\r\n }\r\n }\r\n else if (tooltip && tooltip.followPointer && !tooltip.isHidden) {\r\n anchor = tooltip.getAnchor([{}], e);\r\n tooltip.updatePosition({ plotX: anchor[0], plotY: anchor[1] });\r\n }\r\n },\r\n\r\n /**\r\n * Reset the tracking by hiding the tooltip, the hover series state and the hover point\r\n *\r\n * @param allowMove {Boolean} Instead of destroying the tooltip altogether, allow moving it if possible\r\n */\r\n reset: function(allowMove) {\r\n var pointer = this,\r\n chart = pointer.chart,\r\n hoverSeries = chart.hoverSeries,\r\n hoverPoint = chart.hoverPoint,\r\n tooltip = chart.tooltip,\r\n tooltipPoints =\r\n tooltip && tooltip.shared ? chart.hoverPoints : hoverPoint;\r\n\r\n // Narrow in allowMove\r\n allowMove = allowMove && tooltip && tooltipPoints;\r\n\r\n // Check if the points have moved outside the plot area, #1003\r\n if (allowMove && splat(tooltipPoints)[0].plotX === UNDEFINED) {\r\n allowMove = false;\r\n }\r\n\r\n // Just move the tooltip, #349\r\n if (allowMove) {\r\n tooltip.refresh(tooltipPoints);\r\n\r\n // Full reset\r\n }\r\n else {\r\n if (hoverPoint) {\r\n hoverPoint.onMouseOut();\r\n }\r\n\r\n if (hoverSeries) {\r\n hoverSeries.onMouseOut();\r\n }\r\n\r\n if (tooltip) {\r\n tooltip.hide();\r\n tooltip.hideCrosshairs();\r\n }\r\n\r\n pointer.hoverX = null;\r\n }\r\n },\r\n\r\n /**\r\n * Scale series groups to a certain scale and translation\r\n */\r\n scaleGroups: function(attribs, clip) {\r\n var chart = this.chart,\r\n seriesAttribs;\r\n\r\n // Scale each series\r\n each(chart.series, function(series) {\r\n seriesAttribs = attribs || series.getPlotBox(); // #1701\r\n if (series.xAxis && series.xAxis.zoomEnabled) {\r\n series.group.attr(seriesAttribs);\r\n if (series.markerGroup) {\r\n series.markerGroup.attr(seriesAttribs);\r\n series.markerGroup.clip(clip ? chart.clipRect : null);\r\n }\r\n if (series.dataLabelsGroup) {\r\n series.dataLabelsGroup.attr(seriesAttribs);\r\n }\r\n }\r\n });\r\n\r\n // Clip\r\n chart.clipRect.attr(clip || chart.clipBox);\r\n },\r\n\r\n /**\r\n * Run translation operations\r\n */\r\n pinchTranslate: function(\r\n zoomHor,\r\n zoomVert,\r\n pinchDown,\r\n touches,\r\n transform,\r\n selectionMarker,\r\n clip,\r\n lastValidTouch\r\n ) {\r\n if (zoomHor) {\r\n this.pinchTranslateDirection(\r\n true,\r\n pinchDown,\r\n touches,\r\n transform,\r\n selectionMarker,\r\n clip,\r\n lastValidTouch\r\n );\r\n }\r\n if (zoomVert) {\r\n this.pinchTranslateDirection(\r\n false,\r\n pinchDown,\r\n touches,\r\n transform,\r\n selectionMarker,\r\n clip,\r\n lastValidTouch\r\n );\r\n }\r\n },\r\n\r\n /**\r\n * Run translation operations for each direction (horizontal and vertical) independently\r\n */\r\n pinchTranslateDirection: function(\r\n horiz,\r\n pinchDown,\r\n touches,\r\n transform,\r\n selectionMarker,\r\n clip,\r\n lastValidTouch,\r\n forcedScale\r\n ) {\r\n var chart = this.chart,\r\n xy = horiz ? \"x\" : \"y\",\r\n XY = horiz ? \"X\" : \"Y\",\r\n sChartXY = \"chart\" + XY,\r\n wh = horiz ? \"width\" : \"height\",\r\n plotLeftTop = chart[\"plot\" + (horiz ? \"Left\" : \"Top\")],\r\n selectionWH,\r\n selectionXY,\r\n clipXY,\r\n scale = forcedScale || 1,\r\n inverted = chart.inverted,\r\n bounds = chart.bounds[horiz ? \"h\" : \"v\"],\r\n singleTouch = pinchDown.length === 1,\r\n touch0Start = pinchDown[0][sChartXY],\r\n touch0Now = touches[0][sChartXY],\r\n touch1Start = !singleTouch && pinchDown[1][sChartXY],\r\n touch1Now = !singleTouch && touches[1][sChartXY],\r\n outOfBounds,\r\n transformScale,\r\n scaleKey,\r\n setScale = function() {\r\n if (!singleTouch && mathAbs(touch0Start - touch1Start) > 20) {\r\n // Don't zoom if fingers are too close on this axis\r\n scale =\r\n forcedScale ||\r\n mathAbs(touch0Now - touch1Now) /\r\n mathAbs(touch0Start - touch1Start);\r\n }\r\n\r\n clipXY = (plotLeftTop - touch0Now) / scale + touch0Start;\r\n selectionWH = chart[\"plot\" + (horiz ? \"Width\" : \"Height\")] / scale;\r\n };\r\n\r\n // Set the scale, first pass\r\n setScale();\r\n\r\n selectionXY = clipXY; // the clip position (x or y) is altered if out of bounds, the selection position is not\r\n\r\n // Out of bounds\r\n if (selectionXY < bounds.min) {\r\n selectionXY = bounds.min;\r\n outOfBounds = true;\r\n }\r\n else if (selectionXY + selectionWH > bounds.max) {\r\n selectionXY = bounds.max - selectionWH;\r\n outOfBounds = true;\r\n }\r\n\r\n // Is the chart dragged off its bounds, determined by dataMin and dataMax?\r\n if (outOfBounds) {\r\n // Modify the touchNow position in order to create an elastic drag movement. This indicates\r\n // to the user that the chart is responsive but can't be dragged further.\r\n touch0Now -= 0.8 * (touch0Now - lastValidTouch[xy][0]);\r\n if (!singleTouch) {\r\n touch1Now -= 0.8 * (touch1Now - lastValidTouch[xy][1]);\r\n }\r\n\r\n // Set the scale, second pass to adapt to the modified touchNow positions\r\n setScale();\r\n }\r\n else {\r\n lastValidTouch[xy] = [touch0Now, touch1Now];\r\n }\r\n\r\n // Set geometry for clipping, selection and transformation\r\n if (!inverted) {\r\n // TODO: implement clipping for inverted charts\r\n clip[xy] = clipXY - plotLeftTop;\r\n clip[wh] = selectionWH;\r\n }\r\n scaleKey = inverted ? (horiz ? \"scaleY\" : \"scaleX\") : \"scale\" + XY;\r\n transformScale = inverted ? 1 / scale : scale;\r\n\r\n selectionMarker[wh] = selectionWH;\r\n selectionMarker[xy] = selectionXY;\r\n transform[scaleKey] = scale;\r\n transform[\"translate\" + XY] =\r\n transformScale * plotLeftTop +\r\n (touch0Now - transformScale * touch0Start);\r\n },\r\n\r\n /**\r\n * Handle touch events with two touches\r\n */\r\n pinch: function(e) {\r\n var self = this,\r\n chart = self.chart,\r\n pinchDown = self.pinchDown,\r\n followTouchMove =\r\n chart.tooltip && chart.tooltip.options.followTouchMove,\r\n touches = e.touches,\r\n touchesLength = touches.length,\r\n lastValidTouch = self.lastValidTouch,\r\n zoomHor = self.zoomHor || self.pinchHor,\r\n zoomVert = self.zoomVert || self.pinchVert,\r\n hasZoom = zoomHor || zoomVert,\r\n selectionMarker = self.selectionMarker,\r\n transform = {},\r\n fireClickEvent =\r\n touchesLength === 1 &&\r\n ((self.inClass(e.target, PREFIX + \"tracker\") &&\r\n chart.runTrackerClick) ||\r\n chart.runChartClick),\r\n clip = {};\r\n\r\n // On touch devices, only proceed to trigger click if a handler is defined\r\n if ((hasZoom || followTouchMove) && !fireClickEvent) {\r\n e.preventDefault();\r\n }\r\n\r\n // Normalize each touch\r\n map(touches, function(e) {\r\n return self.normalize(e);\r\n });\r\n\r\n // Register the touch start position\r\n if (e.type === \"touchstart\") {\r\n each(touches, function(e, i) {\r\n pinchDown[i] = { chartX: e.chartX, chartY: e.chartY };\r\n });\r\n lastValidTouch.x = [\r\n pinchDown[0].chartX,\r\n pinchDown[1] && pinchDown[1].chartX\r\n ];\r\n lastValidTouch.y = [\r\n pinchDown[0].chartY,\r\n pinchDown[1] && pinchDown[1].chartY\r\n ];\r\n\r\n // Identify the data bounds in pixels\r\n each(chart.axes, function(axis) {\r\n if (axis.zoomEnabled) {\r\n var bounds = chart.bounds[axis.horiz ? \"h\" : \"v\"],\r\n minPixelPadding = axis.minPixelPadding,\r\n min = axis.toPixels(axis.dataMin),\r\n max = axis.toPixels(axis.dataMax),\r\n absMin = mathMin(min, max),\r\n absMax = mathMax(min, max);\r\n\r\n // Store the bounds for use in the touchmove handler\r\n bounds.min = mathMin(axis.pos, absMin - minPixelPadding);\r\n bounds.max = mathMax(axis.pos + axis.len, absMax + minPixelPadding);\r\n }\r\n });\r\n\r\n // Event type is touchmove, handle panning and pinching\r\n }\r\n else if (pinchDown.length) {\r\n // can be 0 when releasing, if touchend fires first\r\n\r\n // Set the marker\r\n if (!selectionMarker) {\r\n self.selectionMarker = selectionMarker = extend(\r\n {\r\n destroy: noop\r\n },\r\n chart.plotBox\r\n );\r\n }\r\n\r\n self.pinchTranslate(\r\n zoomHor,\r\n zoomVert,\r\n pinchDown,\r\n touches,\r\n transform,\r\n selectionMarker,\r\n clip,\r\n lastValidTouch\r\n );\r\n\r\n self.hasPinched = hasZoom;\r\n\r\n // Scale and translate the groups to provide visual feedback during pinching\r\n self.scaleGroups(transform, clip);\r\n\r\n // Optionally move the tooltip on touchmove\r\n if (!hasZoom && followTouchMove && touchesLength === 1) {\r\n this.runPointActions(self.normalize(e));\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Start a drag operation\r\n */\r\n dragStart: function(e) {\r\n var chart = this.chart;\r\n\r\n // Record the start position\r\n chart.mouseIsDown = e.type;\r\n chart.cancelClick = false;\r\n chart.mouseDownX = this.mouseDownX = e.chartX;\r\n chart.mouseDownY = this.mouseDownY = e.chartY;\r\n },\r\n\r\n /**\r\n * Perform a drag operation in response to a mousemove event while the mouse is down\r\n */\r\n drag: function(e) {\r\n var chart = this.chart,\r\n chartOptions = chart.options.chart,\r\n chartX = e.chartX,\r\n chartY = e.chartY,\r\n zoomHor = this.zoomHor,\r\n zoomVert = this.zoomVert,\r\n plotLeft = chart.plotLeft,\r\n plotTop = chart.plotTop,\r\n plotWidth = chart.plotWidth,\r\n plotHeight = chart.plotHeight,\r\n clickedInside,\r\n size,\r\n mouseDownX = this.mouseDownX,\r\n mouseDownY = this.mouseDownY;\r\n\r\n // If the mouse is outside the plot area, adjust to cooordinates\r\n // inside to prevent the selection marker from going outside\r\n if (chartX < plotLeft) {\r\n chartX = plotLeft;\r\n }\r\n else if (chartX > plotLeft + plotWidth) {\r\n chartX = plotLeft + plotWidth;\r\n }\r\n\r\n if (chartY < plotTop) {\r\n chartY = plotTop;\r\n }\r\n else if (chartY > plotTop + plotHeight) {\r\n chartY = plotTop + plotHeight;\r\n }\r\n\r\n // determine if the mouse has moved more than 10px\r\n this.hasDragged = Math.sqrt(\r\n Math.pow(mouseDownX - chartX, 2) + Math.pow(mouseDownY - chartY, 2)\r\n );\r\n if (this.hasDragged > 10) {\r\n clickedInside = chart.isInsidePlot(\r\n mouseDownX - plotLeft,\r\n mouseDownY - plotTop\r\n );\r\n\r\n // make a selection\r\n if (\r\n chart.hasCartesianSeries &&\r\n (this.zoomX || this.zoomY) &&\r\n clickedInside\r\n ) {\r\n if (!this.selectionMarker) {\r\n this.selectionMarker = chart.renderer\r\n .rect(\r\n plotLeft,\r\n plotTop,\r\n zoomHor ? 1 : plotWidth,\r\n zoomVert ? 1 : plotHeight,\r\n 0\r\n )\r\n .attr({\r\n fill:\r\n chartOptions.selectionMarkerFill || \"rgba(69,114,167,0.25)\",\r\n zIndex: 7\r\n })\r\n .add();\r\n }\r\n }\r\n\r\n // adjust the width of the selection marker\r\n if (this.selectionMarker && zoomHor) {\r\n size = chartX - mouseDownX;\r\n this.selectionMarker.attr({\r\n width: mathAbs(size),\r\n x: (size > 0 ? 0 : size) + mouseDownX\r\n });\r\n }\r\n // adjust the height of the selection marker\r\n if (this.selectionMarker && zoomVert) {\r\n size = chartY - mouseDownY;\r\n this.selectionMarker.attr({\r\n height: mathAbs(size),\r\n y: (size > 0 ? 0 : size) + mouseDownY\r\n });\r\n }\r\n\r\n // panning\r\n if (clickedInside && !this.selectionMarker && chartOptions.panning) {\r\n chart.pan(e, chartOptions.panning);\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * On mouse up or touch end across the entire document, drop the selection.\r\n */\r\n drop: function(e) {\r\n var chart = this.chart,\r\n hasPinched = this.hasPinched;\r\n\r\n if (this.selectionMarker) {\r\n var selectionData = {\r\n xAxis: [],\r\n yAxis: [],\r\n originalEvent: e.originalEvent || e\r\n },\r\n selectionBox = this.selectionMarker,\r\n selectionLeft = selectionBox.x,\r\n selectionTop = selectionBox.y,\r\n runZoom;\r\n // a selection has been made\r\n if (this.hasDragged || hasPinched) {\r\n // record each axis' min and max\r\n each(chart.axes, function(axis) {\r\n if (axis.zoomEnabled) {\r\n var horiz = axis.horiz,\r\n selectionMin = axis.toValue(\r\n horiz ? selectionLeft : selectionTop\r\n ),\r\n selectionMax = axis.toValue(\r\n horiz\r\n ? selectionLeft + selectionBox.width\r\n : selectionTop + selectionBox.height\r\n );\r\n\r\n if (!isNaN(selectionMin) && !isNaN(selectionMax)) {\r\n // #859\r\n selectionData[axis.xOrY + \"Axis\"].push({\r\n axis: axis,\r\n min: mathMin(selectionMin, selectionMax), // for reversed axes,\r\n max: mathMax(selectionMin, selectionMax)\r\n });\r\n runZoom = true;\r\n }\r\n }\r\n });\r\n if (runZoom) {\r\n fireEvent(chart, \"selection\", selectionData, function(args) {\r\n chart.zoom(\r\n extend(args, hasPinched ? { animation: false } : null)\r\n );\r\n });\r\n }\r\n }\r\n this.selectionMarker = this.selectionMarker.destroy();\r\n\r\n // Reset scaling preview\r\n if (hasPinched) {\r\n this.scaleGroups();\r\n }\r\n }\r\n\r\n // Reset all\r\n if (chart) {\r\n // it may be destroyed on mouse up - #877\r\n css(chart.container, { cursor: chart._cursor });\r\n chart.cancelClick = this.hasDragged > 10; // #370\r\n chart.mouseIsDown = this.hasDragged = this.hasPinched = false;\r\n this.pinchDown = [];\r\n }\r\n },\r\n\r\n onContainerMouseDown: function(e) {\r\n e = this.normalize(e);\r\n\r\n // issue #295, dragging not always working in Firefox\r\n if (e.preventDefault) {\r\n e.preventDefault();\r\n }\r\n\r\n this.dragStart(e);\r\n },\r\n\r\n onDocumentMouseUp: function(e) {\r\n this.drop(e);\r\n },\r\n\r\n /**\r\n * Special handler for mouse move that will hide the tooltip when the mouse leaves the plotarea.\r\n * Issue #149 workaround. The mouseleave event does not always fire.\r\n */\r\n onDocumentMouseMove: function(e) {\r\n var chart = this.chart,\r\n chartPosition = this.chartPosition,\r\n hoverSeries = chart.hoverSeries;\r\n\r\n e = this.normalize(e, chartPosition);\r\n\r\n // If we're outside, hide the tooltip\r\n if (\r\n chartPosition &&\r\n hoverSeries &&\r\n !this.inClass(e.target, \"highcharts-tracker\") &&\r\n !chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)\r\n ) {\r\n this.reset();\r\n }\r\n },\r\n\r\n /**\r\n * When mouse leaves the container, hide the tooltip.\r\n */\r\n onContainerMouseLeave: function() {\r\n this.reset();\r\n this.chartPosition = null; // also reset the chart position, used in #149 fix\r\n },\r\n\r\n // The mousemove, touchmove and touchstart event handler\r\n onContainerMouseMove: function(e) {\r\n var chart = this.chart;\r\n\r\n // normalize\r\n e = this.normalize(e);\r\n\r\n // #295\r\n e.returnValue = false;\r\n\r\n if (chart.mouseIsDown === \"mousedown\") {\r\n this.drag(e);\r\n }\r\n\r\n // Show the tooltip and run mouse over events (#977)\r\n if (\r\n (this.inClass(e.target, \"highcharts-tracker\") ||\r\n chart.isInsidePlot(\r\n e.chartX - chart.plotLeft,\r\n e.chartY - chart.plotTop\r\n )) &&\r\n !chart.openMenu\r\n ) {\r\n this.runPointActions(e);\r\n }\r\n },\r\n\r\n /**\r\n * Utility to detect whether an element has, or has a parent with, a specific\r\n * class name. Used on detection of tracker objects and on deciding whether\r\n * hovering the tooltip should cause the active series to mouse out.\r\n */\r\n inClass: function(element, className) {\r\n var elemClassName;\r\n while (element) {\r\n elemClassName = attr(element, \"class\");\r\n if (elemClassName) {\r\n if (elemClassName.indexOf(className) !== -1) {\r\n return true;\r\n }\r\n else if (elemClassName.indexOf(PREFIX + \"container\") !== -1) {\r\n return false;\r\n }\r\n }\r\n element = element.parentNode;\r\n }\r\n },\r\n\r\n onTrackerMouseOut: function(e) {\r\n var series = this.chart.hoverSeries;\r\n if (\r\n series &&\r\n !series.options.stickyTracking &&\r\n !this.inClass(e.toElement || e.relatedTarget, PREFIX + \"tooltip\")\r\n ) {\r\n series.onMouseOut();\r\n }\r\n },\r\n\r\n onContainerClick: function(e) {\r\n var chart = this.chart,\r\n hoverPoint = chart.hoverPoint,\r\n plotLeft = chart.plotLeft,\r\n plotTop = chart.plotTop,\r\n inverted = chart.inverted,\r\n chartPosition,\r\n plotX,\r\n plotY;\r\n\r\n e = this.normalize(e);\r\n e.cancelBubble = true; // IE specific\r\n\r\n if (!chart.cancelClick) {\r\n // On tracker click, fire the series and point events. #783, #1583\r\n if (hoverPoint && this.inClass(e.target, PREFIX + \"tracker\")) {\r\n chartPosition = this.chartPosition;\r\n plotX = hoverPoint.plotX;\r\n plotY = hoverPoint.plotY;\r\n\r\n // add page position info\r\n extend(hoverPoint, {\r\n pageX:\r\n chartPosition.left +\r\n plotLeft +\r\n (inverted ? chart.plotWidth - plotY : plotX),\r\n pageY:\r\n chartPosition.top +\r\n plotTop +\r\n (inverted ? chart.plotHeight - plotX : plotY)\r\n });\r\n\r\n // the series click event\r\n fireEvent(\r\n hoverPoint.series,\r\n \"click\",\r\n extend(e, {\r\n point: hoverPoint\r\n })\r\n );\r\n\r\n // the point click event\r\n if (chart.hoverPoint) {\r\n // it may be destroyed (#1844)\r\n hoverPoint.firePointEvent(\"click\", e);\r\n }\r\n\r\n // When clicking outside a tracker, fire a chart event\r\n }\r\n else {\r\n extend(e, this.getCoordinates(e));\r\n\r\n // fire a click event in the chart\r\n if (chart.isInsidePlot(e.chartX - plotLeft, e.chartY - plotTop)) {\r\n fireEvent(chart, \"click\", e);\r\n }\r\n }\r\n }\r\n },\r\n\r\n onContainerTouchStart: function(e) {\r\n var chart = this.chart;\r\n\r\n if (e.touches.length === 1) {\r\n e = this.normalize(e);\r\n\r\n if (\r\n chart.isInsidePlot(\r\n e.chartX - chart.plotLeft,\r\n e.chartY - chart.plotTop\r\n )\r\n ) {\r\n // Prevent the click pseudo event from firing unless it is set in the options\r\n /*if (!chart.runChartClick) {\r\n\t\t\t\t\te.preventDefault();\r\n\t\t\t\t}*/\r\n\r\n // Run mouse events and display tooltip etc\r\n this.runPointActions(e);\r\n\r\n this.pinch(e);\r\n }\r\n else {\r\n // Hide the tooltip on touching outside the plot area (#1203)\r\n this.reset();\r\n }\r\n }\r\n else if (e.touches.length === 2) {\r\n this.pinch(e);\r\n }\r\n },\r\n\r\n onContainerTouchMove: function(e) {\r\n if (e.touches.length === 1 || e.touches.length === 2) {\r\n this.pinch(e);\r\n }\r\n },\r\n\r\n onDocumentTouchEnd: function(e) {\r\n this.drop(e);\r\n },\r\n\r\n /**\r\n * Set the JS DOM events on the container and document. This method should contain\r\n * a one-to-one assignment between methods and their handlers. Any advanced logic should\r\n * be moved to the handler reflecting the event's name.\r\n */\r\n setDOMEvents: function() {\r\n var pointer = this,\r\n container = pointer.chart.container,\r\n events;\r\n\r\n this._events = events = [\r\n [container, \"onmousedown\", \"onContainerMouseDown\"],\r\n [container, \"onmousemove\", \"onContainerMouseMove\"],\r\n [container, \"onclick\", \"onContainerClick\"],\r\n [container, \"mouseleave\", \"onContainerMouseLeave\"],\r\n [doc, \"mousemove\", \"onDocumentMouseMove\"],\r\n [doc, \"mouseup\", \"onDocumentMouseUp\"]\r\n ];\r\n\r\n if (hasTouch) {\r\n events.push(\r\n [container, \"ontouchstart\", \"onContainerTouchStart\"],\r\n [container, \"ontouchmove\", \"onContainerTouchMove\"],\r\n [doc, \"touchend\", \"onDocumentTouchEnd\"]\r\n );\r\n }\r\n\r\n each(events, function(eventConfig) {\r\n // First, create the callback function that in turn calls the method on Pointer\r\n pointer[\"_\" + eventConfig[2]] = function(e) {\r\n pointer[eventConfig[2]](e);\r\n };\r\n\r\n // Now attach the function, either as a direct property or through addEvent\r\n if (eventConfig[1].indexOf(\"on\") === 0) {\r\n eventConfig[0][eventConfig[1]] = pointer[\"_\" + eventConfig[2]];\r\n }\r\n else {\r\n addEvent(\r\n eventConfig[0],\r\n eventConfig[1],\r\n pointer[\"_\" + eventConfig[2]]\r\n );\r\n }\r\n });\r\n },\r\n\r\n /**\r\n * Destroys the Pointer object and disconnects DOM events.\r\n */\r\n destroy: function() {\r\n var pointer = this;\r\n\r\n // Release all DOM events\r\n each(pointer._events, function(eventConfig) {\r\n if (eventConfig[1].indexOf(\"on\") === 0) {\r\n eventConfig[0][eventConfig[1]] = null; // delete breaks oldIE\r\n }\r\n else {\r\n removeEvent(\r\n eventConfig[0],\r\n eventConfig[1],\r\n pointer[\"_\" + eventConfig[2]]\r\n );\r\n }\r\n });\r\n delete pointer._events;\r\n\r\n // memory and CPU leak\r\n clearInterval(pointer.tooltipTimeout);\r\n }\r\n };\r\n /**\r\n * The overview of the chart's series\r\n */\r\n function Legend(chart, options) {\r\n this.init(chart, options);\r\n }\r\n\r\n Legend.prototype = {\r\n /**\r\n * Initialize the legend\r\n */\r\n init: function(chart, options) {\r\n var legend = this,\r\n itemStyle = options.itemStyle,\r\n padding = pick(options.padding, 8),\r\n itemMarginTop = options.itemMarginTop || 0;\r\n\r\n this.options = options;\r\n\r\n if (!options.enabled) {\r\n return;\r\n }\r\n\r\n legend.baseline = pInt(itemStyle.fontSize) + 3 + itemMarginTop; // used in Series prototype\r\n legend.itemStyle = itemStyle;\r\n legend.itemHiddenStyle = merge(itemStyle, options.itemHiddenStyle);\r\n legend.itemMarginTop = itemMarginTop;\r\n legend.padding = padding;\r\n legend.initialItemX = padding;\r\n legend.initialItemY = padding - 5; // 5 is the number of pixels above the text\r\n legend.maxItemWidth = 0;\r\n legend.chart = chart;\r\n legend.itemHeight = 0;\r\n legend.lastLineHeight = 0;\r\n\r\n // Render it\r\n legend.render();\r\n\r\n // move checkboxes\r\n addEvent(legend.chart, \"endResize\", function() {\r\n legend.positionCheckboxes();\r\n });\r\n },\r\n\r\n /**\r\n * Set the colors for the legend item\r\n * @param {Object} item A Series or Point instance\r\n * @param {Object} visible Dimmed or colored\r\n */\r\n colorizeItem: function(item, visible) {\r\n var legend = this,\r\n options = legend.options,\r\n legendItem = item.legendItem,\r\n legendLine = item.legendLine,\r\n legendSymbol = item.legendSymbol,\r\n hiddenColor = legend.itemHiddenStyle.color,\r\n textColor = visible ? options.itemStyle.color : hiddenColor,\r\n symbolColor = visible ? item.color : hiddenColor,\r\n markerOptions = item.options && item.options.marker,\r\n symbolAttr = {\r\n stroke: symbolColor,\r\n fill: symbolColor\r\n },\r\n key,\r\n val;\r\n\r\n if (legendItem) {\r\n legendItem.css({ fill: textColor, color: textColor }); // color for #1553, oldIE\r\n }\r\n if (legendLine) {\r\n legendLine.attr({ stroke: symbolColor });\r\n }\r\n\r\n if (legendSymbol) {\r\n // Apply marker options\r\n if (markerOptions && legendSymbol.isMarker) {\r\n // #585\r\n markerOptions = item.convertAttribs(markerOptions);\r\n for (key in markerOptions) {\r\n val = markerOptions[key];\r\n if (val !== UNDEFINED) {\r\n symbolAttr[key] = val;\r\n }\r\n }\r\n }\r\n\r\n legendSymbol.attr(symbolAttr);\r\n }\r\n },\r\n\r\n /**\r\n * Position the legend item\r\n * @param {Object} item A Series or Point instance\r\n */\r\n positionItem: function(item) {\r\n var legend = this,\r\n options = legend.options,\r\n symbolPadding = options.symbolPadding,\r\n ltr = !options.rtl,\r\n legendItemPos = item._legendItemPos,\r\n itemX = legendItemPos[0],\r\n itemY = legendItemPos[1],\r\n checkbox = item.checkbox;\r\n\r\n if (item.legendGroup) {\r\n item.legendGroup.translate(\r\n ltr ? itemX : legend.legendWidth - itemX - 2 * symbolPadding - 4,\r\n itemY\r\n );\r\n }\r\n\r\n if (checkbox) {\r\n checkbox.x = itemX;\r\n checkbox.y = itemY;\r\n }\r\n },\r\n\r\n /**\r\n * Destroy a single legend item\r\n * @param {Object} item The series or point\r\n */\r\n destroyItem: function(item) {\r\n var checkbox = item.checkbox;\r\n\r\n // destroy SVG elements\r\n each(\r\n [\"legendItem\", \"legendLine\", \"legendSymbol\", \"legendGroup\"],\r\n function(key) {\r\n if (item[key]) {\r\n item[key] = item[key].destroy();\r\n }\r\n }\r\n );\r\n\r\n if (checkbox) {\r\n discardElement(item.checkbox);\r\n }\r\n },\r\n\r\n /**\r\n * Destroys the legend.\r\n */\r\n destroy: function() {\r\n var legend = this,\r\n legendGroup = legend.group,\r\n box = legend.box;\r\n\r\n if (box) {\r\n legend.box = box.destroy();\r\n }\r\n\r\n if (legendGroup) {\r\n legend.group = legendGroup.destroy();\r\n }\r\n },\r\n\r\n /**\r\n * Position the checkboxes after the width is determined\r\n */\r\n positionCheckboxes: function(scrollOffset) {\r\n var alignAttr = this.group.alignAttr,\r\n translateY,\r\n clipHeight = this.clipHeight || this.legendHeight;\r\n\r\n if (alignAttr) {\r\n translateY = alignAttr.translateY;\r\n each(this.allItems, function(item) {\r\n var checkbox = item.checkbox,\r\n top;\r\n\r\n if (checkbox) {\r\n top = translateY + checkbox.y + (scrollOffset || 0) + 3;\r\n css(checkbox, {\r\n left:\r\n alignAttr.translateX +\r\n item.legendItemWidth +\r\n checkbox.x -\r\n 20 +\r\n PX,\r\n top: top + PX,\r\n display:\r\n top > translateY - 6 && top < translateY + clipHeight - 6\r\n ? \"\"\r\n : NONE\r\n });\r\n }\r\n });\r\n }\r\n },\r\n\r\n /**\r\n * Render the legend title on top of the legend\r\n */\r\n renderTitle: function() {\r\n var options = this.options,\r\n padding = this.padding,\r\n titleOptions = options.title,\r\n titleHeight = 0,\r\n bBox;\r\n\r\n if (titleOptions.text) {\r\n if (!this.title) {\r\n this.title = this.chart.renderer\r\n .label(\r\n titleOptions.text,\r\n padding - 3,\r\n padding - 4,\r\n null,\r\n null,\r\n null,\r\n null,\r\n null,\r\n \"legend-title\"\r\n )\r\n .attr({ zIndex: 1 })\r\n .css(titleOptions.style)\r\n .add(this.group);\r\n }\r\n bBox = this.title.getBBox();\r\n titleHeight = bBox.height;\r\n this.offsetWidth = bBox.width; // #1717\r\n this.contentGroup.attr({ translateY: titleHeight });\r\n }\r\n this.titleHeight = titleHeight;\r\n },\r\n\r\n /**\r\n * Render a single specific legend item\r\n * @param {Object} item A series or point\r\n */\r\n renderItem: function(item) {\r\n var legend = this,\r\n chart = legend.chart,\r\n renderer = chart.renderer,\r\n options = legend.options,\r\n horizontal = options.layout === \"horizontal\",\r\n symbolWidth = options.symbolWidth,\r\n symbolPadding = options.symbolPadding,\r\n itemStyle = legend.itemStyle,\r\n itemHiddenStyle = legend.itemHiddenStyle,\r\n padding = legend.padding,\r\n itemDistance = horizontal ? pick(options.itemDistance, 8) : 0,\r\n ltr = !options.rtl,\r\n itemHeight,\r\n widthOption = options.width,\r\n itemMarginBottom = options.itemMarginBottom || 0,\r\n itemMarginTop = legend.itemMarginTop,\r\n initialItemX = legend.initialItemX,\r\n bBox,\r\n itemWidth,\r\n li = item.legendItem,\r\n series = item.series || item,\r\n itemOptions = series.options,\r\n showCheckbox = itemOptions.showCheckbox,\r\n useHTML = options.useHTML;\r\n\r\n if (!li) {\r\n // generate it once, later move it\r\n\r\n // Generate the group box\r\n // A group to hold the symbol and text. Text is to be appended in Legend class.\r\n item.legendGroup = renderer\r\n .g(\"legend-item\")\r\n .attr({ zIndex: 1 })\r\n .add(legend.scrollGroup);\r\n\r\n // Draw the legend symbol inside the group box\r\n series.drawLegendSymbol(legend, item);\r\n\r\n // Generate the list item text and add it to the group\r\n item.legendItem = li = renderer\r\n .text(\r\n options.labelFormat\r\n ? format(options.labelFormat, item)\r\n : options.labelFormatter.call(item),\r\n ltr ? symbolWidth + symbolPadding : -symbolPadding,\r\n legend.baseline,\r\n useHTML\r\n )\r\n .css(merge(item.visible ? itemStyle : itemHiddenStyle)) // merge to prevent modifying original (#1021)\r\n .attr({\r\n align: ltr ? \"left\" : \"right\",\r\n zIndex: 2\r\n })\r\n .add(item.legendGroup);\r\n\r\n // Set the events on the item group, or in case of useHTML, the item itself (#1249)\r\n (useHTML ? li : item.legendGroup)\r\n .on(\"mouseover\", function() {\r\n item.setState(HOVER_STATE);\r\n li.css(legend.options.itemHoverStyle);\r\n })\r\n .on(\"mouseout\", function() {\r\n li.css(item.visible ? itemStyle : itemHiddenStyle);\r\n item.setState();\r\n })\r\n .on(\"click\", function(event) {\r\n var strLegendItemClick = \"legendItemClick\",\r\n fnLegendItemClick = function() {\r\n item.setVisible();\r\n };\r\n\r\n // Pass over the click/touch event. #4.\r\n event = {\r\n browserEvent: event\r\n };\r\n\r\n // click the name or symbol\r\n if (item.firePointEvent) {\r\n // point\r\n item.firePointEvent(strLegendItemClick, event, fnLegendItemClick);\r\n }\r\n else {\r\n fireEvent(item, strLegendItemClick, event, fnLegendItemClick);\r\n }\r\n });\r\n\r\n // Colorize the items\r\n legend.colorizeItem(item, item.visible);\r\n\r\n // add the HTML checkbox on top\r\n if (itemOptions && showCheckbox) {\r\n item.checkbox = createElement(\r\n \"input\",\r\n {\r\n type: \"checkbox\",\r\n checked: item.selected,\r\n defaultChecked: item.selected // required by IE7\r\n },\r\n options.itemCheckboxStyle,\r\n chart.container\r\n );\r\n\r\n addEvent(item.checkbox, \"click\", function(event) {\r\n var target = event.target;\r\n fireEvent(\r\n item,\r\n \"checkboxClick\",\r\n {\r\n checked: target.checked\r\n },\r\n function() {\r\n item.select();\r\n }\r\n );\r\n });\r\n }\r\n }\r\n\r\n // calculate the positions for the next line\r\n bBox = li.getBBox();\r\n\r\n itemWidth = item.legendItemWidth =\r\n options.itemWidth ||\r\n symbolWidth +\r\n symbolPadding +\r\n bBox.width +\r\n itemDistance +\r\n (showCheckbox ? 20 : 0);\r\n legend.itemHeight = itemHeight = bBox.height;\r\n\r\n // if the item exceeds the width, start a new line\r\n if (\r\n horizontal &&\r\n legend.itemX - initialItemX + itemWidth >\r\n (widthOption || chart.chartWidth - 2 * padding - initialItemX)\r\n ) {\r\n legend.itemX = initialItemX;\r\n legend.itemY +=\r\n itemMarginTop + legend.lastLineHeight + itemMarginBottom;\r\n legend.lastLineHeight = 0; // reset for next line\r\n }\r\n\r\n // If the item exceeds the height, start a new column\r\n /*if (!horizontal && legend.itemY + options.y + itemHeight > chart.chartHeight - spacingTop - spacingBottom) {\r\n\t\t\tlegend.itemY = legend.initialItemY;\r\n\t\t\tlegend.itemX += legend.maxItemWidth;\r\n\t\t\tlegend.maxItemWidth = 0;\r\n\t\t}*/\r\n\r\n // Set the edge positions\r\n legend.maxItemWidth = mathMax(legend.maxItemWidth, itemWidth);\r\n legend.lastItemY = itemMarginTop + legend.itemY + itemMarginBottom;\r\n legend.lastLineHeight = mathMax(itemHeight, legend.lastLineHeight); // #915\r\n\r\n // cache the position of the newly generated or reordered items\r\n item._legendItemPos = [legend.itemX, legend.itemY];\r\n\r\n // advance\r\n if (horizontal) {\r\n legend.itemX += itemWidth;\r\n }\r\n else {\r\n legend.itemY += itemMarginTop + itemHeight + itemMarginBottom;\r\n legend.lastLineHeight = itemHeight;\r\n }\r\n\r\n // the width of the widest item\r\n legend.offsetWidth =\r\n widthOption ||\r\n mathMax(\r\n (horizontal\r\n ? legend.itemX - initialItemX - itemDistance\r\n : itemWidth) + padding,\r\n legend.offsetWidth\r\n );\r\n },\r\n\r\n /**\r\n * Render the legend. This method can be called both before and after\r\n * chart.render. If called after, it will only rearrange items instead\r\n * of creating new ones.\r\n */\r\n render: function() {\r\n var legend = this,\r\n chart = legend.chart,\r\n renderer = chart.renderer,\r\n legendGroup = legend.group,\r\n allItems,\r\n display,\r\n legendWidth,\r\n legendHeight,\r\n box = legend.box,\r\n options = legend.options,\r\n padding = legend.padding,\r\n legendBorderWidth = options.borderWidth,\r\n legendBackgroundColor = options.backgroundColor;\r\n\r\n legend.itemX = legend.initialItemX;\r\n legend.itemY = legend.initialItemY;\r\n legend.offsetWidth = 0;\r\n legend.lastItemY = 0;\r\n\r\n if (!legendGroup) {\r\n legend.group = legendGroup = renderer\r\n .g(\"legend\")\r\n .attr({ zIndex: 7 })\r\n .add();\r\n legend.contentGroup = renderer\r\n .g()\r\n .attr({ zIndex: 1 }) // above background\r\n .add(legendGroup);\r\n legend.scrollGroup = renderer.g().add(legend.contentGroup);\r\n }\r\n\r\n legend.renderTitle();\r\n\r\n // add each series or point\r\n allItems = [];\r\n each(chart.series, function(serie) {\r\n var seriesOptions = serie.options;\r\n\r\n // Handle showInLegend. If the series is linked to another series, defaults to false.\r\n if (\r\n !pick(\r\n seriesOptions.showInLegend,\r\n seriesOptions.linkedTo === UNDEFINED ? UNDEFINED : false,\r\n true\r\n )\r\n ) {\r\n return;\r\n }\r\n\r\n // use points or series for the legend item depending on legendType\r\n allItems = allItems.concat(\r\n serie.legendItems ||\r\n (seriesOptions.legendType === \"point\" ? serie.data : serie)\r\n );\r\n });\r\n\r\n // sort by legendIndex\r\n stableSort(allItems, function(a, b) {\r\n return (\r\n ((a.options && a.options.legendIndex) || 0) -\r\n ((b.options && b.options.legendIndex) || 0)\r\n );\r\n });\r\n\r\n // reversed legend\r\n if (options.reversed) {\r\n allItems.reverse();\r\n }\r\n\r\n legend.allItems = allItems;\r\n legend.display = display = !!allItems.length;\r\n\r\n // render the items\r\n each(allItems, function(item) {\r\n legend.renderItem(item);\r\n });\r\n\r\n // Draw the border\r\n legendWidth = options.width || legend.offsetWidth;\r\n legendHeight =\r\n legend.lastItemY + legend.lastLineHeight + legend.titleHeight;\r\n\r\n legendHeight = legend.handleOverflow(legendHeight);\r\n\r\n if (legendBorderWidth || legendBackgroundColor) {\r\n legendWidth += padding;\r\n legendHeight += padding;\r\n\r\n if (!box) {\r\n legend.box = box = renderer\r\n .rect(\r\n 0,\r\n 0,\r\n legendWidth,\r\n legendHeight,\r\n options.borderRadius,\r\n legendBorderWidth || 0\r\n )\r\n .attr({\r\n stroke: options.borderColor,\r\n \"stroke-width\": legendBorderWidth || 0,\r\n fill: legendBackgroundColor || NONE\r\n })\r\n .add(legendGroup)\r\n .shadow(options.shadow);\r\n box.isNew = true;\r\n }\r\n else if (legendWidth > 0 && legendHeight > 0) {\r\n box[box.isNew ? \"attr\" : \"animate\"](\r\n box.crisp(null, null, null, legendWidth, legendHeight)\r\n );\r\n box.isNew = false;\r\n }\r\n\r\n // hide the border if no items\r\n box[display ? \"show\" : \"hide\"]();\r\n }\r\n\r\n legend.legendWidth = legendWidth;\r\n legend.legendHeight = legendHeight;\r\n\r\n // Now that the legend width and height are established, put the items in the\r\n // final position\r\n each(allItems, function(item) {\r\n legend.positionItem(item);\r\n });\r\n\r\n // 1.x compatibility: positioning based on style\r\n /*var props = ['left', 'right', 'top', 'bottom'],\r\n\t\t\tprop,\r\n\t\t\ti = 4;\r\n\t\twhile (i--) {\r\n\t\t\tprop = props[i];\r\n\t\t\tif (options.style[prop] && options.style[prop] !== 'auto') {\r\n\t\t\t\toptions[i < 2 ? 'align' : 'verticalAlign'] = prop;\r\n\t\t\t\toptions[i < 2 ? 'x' : 'y'] = pInt(options.style[prop]) * (i % 2 ? -1 : 1);\r\n\t\t\t}\r\n\t\t}*/\r\n\r\n if (display) {\r\n legendGroup.align(\r\n extend(\r\n {\r\n width: legendWidth,\r\n height: legendHeight\r\n },\r\n options\r\n ),\r\n true,\r\n \"spacingBox\"\r\n );\r\n }\r\n\r\n if (!chart.isResizing) {\r\n this.positionCheckboxes();\r\n }\r\n },\r\n\r\n /**\r\n * Set up the overflow handling by adding navigation with up and down arrows below the\r\n * legend.\r\n */\r\n handleOverflow: function(legendHeight) {\r\n var legend = this,\r\n chart = this.chart,\r\n renderer = chart.renderer,\r\n pageCount,\r\n options = this.options,\r\n optionsY = options.y,\r\n alignTop = options.verticalAlign === \"top\",\r\n spaceHeight =\r\n chart.spacingBox.height +\r\n (alignTop ? -optionsY : optionsY) -\r\n this.padding,\r\n maxHeight = options.maxHeight,\r\n clipHeight,\r\n clipRect = this.clipRect,\r\n navOptions = options.navigation,\r\n animation = pick(navOptions.animation, true),\r\n arrowSize = navOptions.arrowSize || 12,\r\n nav = this.nav;\r\n\r\n // Adjust the height\r\n if (options.layout === \"horizontal\") {\r\n spaceHeight /= 2;\r\n }\r\n if (maxHeight) {\r\n spaceHeight = mathMin(spaceHeight, maxHeight);\r\n }\r\n\r\n // Reset the legend height and adjust the clipping rectangle\r\n if (legendHeight > spaceHeight && !options.useHTML) {\r\n this.clipHeight = clipHeight = spaceHeight - 20 - this.titleHeight;\r\n this.pageCount = pageCount = mathCeil(legendHeight / clipHeight);\r\n this.currentPage = pick(this.currentPage, 1);\r\n this.fullHeight = legendHeight;\r\n\r\n // Only apply clipping if needed. Clipping causes blurred legend in PDF export (#1787)\r\n if (!clipRect) {\r\n clipRect = legend.clipRect = renderer.clipRect(0, 0, 9999, 0);\r\n legend.contentGroup.clip(clipRect);\r\n }\r\n clipRect.attr({\r\n height: clipHeight\r\n });\r\n\r\n // Add navigation elements\r\n if (!nav) {\r\n this.nav = nav = renderer\r\n .g()\r\n .attr({ zIndex: 1 })\r\n .add(this.group);\r\n this.up = renderer\r\n .symbol(\"triangle\", 0, 0, arrowSize, arrowSize)\r\n .on(\"click\", function() {\r\n legend.scroll(-1, animation);\r\n })\r\n .add(nav);\r\n this.pager = renderer\r\n .text(\"\", 15, 10)\r\n .css(navOptions.style)\r\n .add(nav);\r\n this.down = renderer\r\n .symbol(\"triangle-down\", 0, 0, arrowSize, arrowSize)\r\n .on(\"click\", function() {\r\n legend.scroll(1, animation);\r\n })\r\n .add(nav);\r\n }\r\n\r\n // Set initial position\r\n legend.scroll(0);\r\n\r\n legendHeight = spaceHeight;\r\n }\r\n else if (nav) {\r\n clipRect.attr({\r\n height: chart.chartHeight\r\n });\r\n nav.hide();\r\n this.scrollGroup.attr({\r\n translateY: 1\r\n });\r\n this.clipHeight = 0; // #1379\r\n }\r\n\r\n return legendHeight;\r\n },\r\n\r\n /**\r\n * Scroll the legend by a number of pages\r\n * @param {Object} scrollBy\r\n * @param {Object} animation\r\n */\r\n scroll: function(scrollBy, animation) {\r\n var pageCount = this.pageCount,\r\n currentPage = this.currentPage + scrollBy,\r\n clipHeight = this.clipHeight,\r\n navOptions = this.options.navigation,\r\n activeColor = navOptions.activeColor,\r\n inactiveColor = navOptions.inactiveColor,\r\n pager = this.pager,\r\n padding = this.padding,\r\n scrollOffset;\r\n\r\n // When resizing while looking at the last page\r\n if (currentPage > pageCount) {\r\n currentPage = pageCount;\r\n }\r\n\r\n if (currentPage > 0) {\r\n if (animation !== UNDEFINED) {\r\n setAnimation(animation, this.chart);\r\n }\r\n\r\n this.nav.attr({\r\n translateX: padding,\r\n translateY: clipHeight + 7 + this.titleHeight,\r\n visibility: VISIBLE\r\n });\r\n this.up\r\n .attr({\r\n fill: currentPage === 1 ? inactiveColor : activeColor\r\n })\r\n .css({\r\n cursor: currentPage === 1 ? \"default\" : \"pointer\"\r\n });\r\n pager.attr({\r\n text: currentPage + \"/\" + this.pageCount\r\n });\r\n this.down\r\n .attr({\r\n x: 18 + this.pager.getBBox().width, // adjust to text width\r\n fill: currentPage === pageCount ? inactiveColor : activeColor\r\n })\r\n .css({\r\n cursor: currentPage === pageCount ? \"default\" : \"pointer\"\r\n });\r\n\r\n scrollOffset =\r\n -mathMin(\r\n clipHeight * (currentPage - 1),\r\n this.fullHeight - clipHeight + padding\r\n ) + 1;\r\n this.scrollGroup.animate({\r\n translateY: scrollOffset\r\n });\r\n pager.attr({\r\n text: currentPage + \"/\" + pageCount\r\n });\r\n\r\n this.currentPage = currentPage;\r\n this.positionCheckboxes(scrollOffset);\r\n }\r\n }\r\n };\r\n\r\n // Workaround for #2030, horizontal legend items not displaying in IE11 Preview.\r\n // TODO: When IE11 is released, check again for this bug, and remove the fix\r\n // or make a better one.\r\n if (/Trident\\/7\\.0/.test(userAgent)) {\r\n wrap(Legend.prototype, \"positionItem\", function(proceed, item) {\r\n var legend = this,\r\n runPositionItem = function() {\r\n proceed.call(legend, item);\r\n };\r\n\r\n if (legend.chart.renderer.forExport) {\r\n runPositionItem();\r\n }\r\n else {\r\n setTimeout(runPositionItem);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * The chart class\r\n * @param {Object} options\r\n * @param {Function} callback Function to run when the chart has loaded\r\n */\r\n function Chart() {\r\n this.init.apply(this, arguments);\r\n }\r\n\r\n Chart.prototype = {\r\n /**\r\n * Initialize the chart\r\n */\r\n init: function(userOptions, callback) {\r\n // Handle regular options\r\n var options,\r\n seriesOptions = userOptions.series; // skip merging data points to increase performance\r\n\r\n userOptions.series = null;\r\n options = merge(defaultOptions, userOptions); // do the merge\r\n options.series = userOptions.series = seriesOptions; // set back the series data\r\n\r\n var optionsChart = options.chart;\r\n\r\n // Create margin & spacing array\r\n this.margin = this.splashArray(\"margin\", optionsChart);\r\n this.spacing = this.splashArray(\"spacing\", optionsChart);\r\n\r\n var chartEvents = optionsChart.events;\r\n\r\n //this.runChartClick = chartEvents && !!chartEvents.click;\r\n this.bounds = { h: {}, v: {} }; // Pixel data bounds for touch zoom\r\n\r\n this.callback = callback;\r\n this.isResizing = 0;\r\n this.options = options;\r\n //chartTitleOptions = UNDEFINED;\r\n //chartSubtitleOptions = UNDEFINED;\r\n\r\n this.axes = [];\r\n this.series = [];\r\n this.hasCartesianSeries = optionsChart.showAxes;\r\n //this.axisOffset = UNDEFINED;\r\n //this.maxTicks = UNDEFINED; // handle the greatest amount of ticks on grouped axes\r\n //this.inverted = UNDEFINED;\r\n //this.loadingShown = UNDEFINED;\r\n //this.container = UNDEFINED;\r\n //this.chartWidth = UNDEFINED;\r\n //this.chartHeight = UNDEFINED;\r\n //this.marginRight = UNDEFINED;\r\n //this.marginBottom = UNDEFINED;\r\n //this.containerWidth = UNDEFINED;\r\n //this.containerHeight = UNDEFINED;\r\n //this.oldChartWidth = UNDEFINED;\r\n //this.oldChartHeight = UNDEFINED;\r\n\r\n //this.renderTo = UNDEFINED;\r\n //this.renderToClone = UNDEFINED;\r\n\r\n //this.spacingBox = UNDEFINED\r\n\r\n //this.legend = UNDEFINED;\r\n\r\n // Elements\r\n //this.chartBackground = UNDEFINED;\r\n //this.plotBackground = UNDEFINED;\r\n //this.plotBGImage = UNDEFINED;\r\n //this.plotBorder = UNDEFINED;\r\n //this.loadingDiv = UNDEFINED;\r\n //this.loadingSpan = UNDEFINED;\r\n\r\n var chart = this,\r\n eventType;\r\n\r\n // Add the chart to the global lookup\r\n chart.index = charts.length;\r\n charts.push(chart);\r\n\r\n // Set up auto resize\r\n if (optionsChart.reflow !== false) {\r\n addEvent(chart, \"load\", function() {\r\n chart.initReflow();\r\n });\r\n }\r\n\r\n // Chart event handlers\r\n if (chartEvents) {\r\n for (eventType in chartEvents) {\r\n addEvent(chart, eventType, chartEvents[eventType]);\r\n }\r\n }\r\n\r\n chart.xAxis = [];\r\n chart.yAxis = [];\r\n\r\n // Expose methods and variables\r\n chart.animation = useCanVG ? false : pick(optionsChart.animation, true);\r\n chart.pointCount = 0;\r\n chart.counters = new ChartCounters();\r\n\r\n chart.firstRender();\r\n },\r\n\r\n /**\r\n * Initialize an individual series, called internally before render time\r\n */\r\n initSeries: function(options) {\r\n var chart = this,\r\n optionsChart = chart.options.chart,\r\n type =\r\n options.type || optionsChart.type || optionsChart.defaultSeriesType,\r\n series,\r\n constr = seriesTypes[type];\r\n\r\n // No such series type\r\n if (!constr) {\r\n error(17, true);\r\n }\r\n\r\n series = new constr();\r\n series.init(this, options);\r\n return series;\r\n },\r\n\r\n /**\r\n * Add a series dynamically after time\r\n *\r\n * @param {Object} options The config options\r\n * @param {Boolean} redraw Whether to redraw the chart after adding. Defaults to true.\r\n * @param {Boolean|Object} animation Whether to apply animation, and optionally animation\r\n * configuration\r\n *\r\n * @return {Object} series The newly created series object\r\n */\r\n addSeries: function(options, redraw, animation) {\r\n var series,\r\n chart = this;\r\n\r\n if (options) {\r\n redraw = pick(redraw, true); // defaults to true\r\n\r\n fireEvent(chart, \"addSeries\", { options: options }, function() {\r\n series = chart.initSeries(options);\r\n\r\n chart.isDirtyLegend = true; // the series array is out of sync with the display\r\n chart.linkSeries();\r\n if (redraw) {\r\n chart.redraw(animation);\r\n }\r\n });\r\n }\r\n\r\n return series;\r\n },\r\n\r\n /**\r\n * Add an axis to the chart\r\n * @param {Object} options The axis option\r\n * @param {Boolean} isX Whether it is an X axis or a value axis\r\n */\r\n addAxis: function(options, isX, redraw, animation) {\r\n var key = isX ? \"xAxis\" : \"yAxis\",\r\n chartOptions = this.options,\r\n axis;\r\n\r\n /*jslint unused: false*/\r\n axis = new Axis(\r\n this,\r\n merge(options, {\r\n index: this[key].length,\r\n isX: isX\r\n })\r\n );\r\n /*jslint unused: true*/\r\n\r\n // Push the new axis options to the chart options\r\n chartOptions[key] = splat(chartOptions[key] || {});\r\n chartOptions[key].push(options);\r\n\r\n if (pick(redraw, true)) {\r\n this.redraw(animation);\r\n }\r\n },\r\n\r\n /**\r\n * Check whether a given point is within the plot area\r\n *\r\n * @param {Number} plotX Pixel x relative to the plot area\r\n * @param {Number} plotY Pixel y relative to the plot area\r\n * @param {Boolean} inverted Whether the chart is inverted\r\n */\r\n isInsidePlot: function(plotX, plotY, inverted) {\r\n var x = inverted ? plotY : plotX,\r\n y = inverted ? plotX : plotY;\r\n\r\n return x >= 0 && x <= this.plotWidth && y >= 0 && y <= this.plotHeight;\r\n },\r\n\r\n /**\r\n * Adjust all axes tick amounts\r\n */\r\n adjustTickAmounts: function() {\r\n if (this.options.chart.alignTicks !== false) {\r\n each(this.axes, function(axis) {\r\n axis.adjustTickAmount();\r\n });\r\n }\r\n this.maxTicks = null;\r\n },\r\n\r\n /**\r\n * Redraw legend, axes or series based on updated data\r\n *\r\n * @param {Boolean|Object} animation Whether to apply animation, and optionally animation\r\n * configuration\r\n */\r\n redraw: function(animation) {\r\n var chart = this,\r\n axes = chart.axes,\r\n series = chart.series,\r\n pointer = chart.pointer,\r\n legend = chart.legend,\r\n redrawLegend = chart.isDirtyLegend,\r\n hasStackedSeries,\r\n hasDirtyStacks,\r\n isDirtyBox = chart.isDirtyBox, // todo: check if it has actually changed?\r\n seriesLength = series.length,\r\n i = seriesLength,\r\n serie,\r\n renderer = chart.renderer,\r\n isHiddenChart = renderer.isHidden(),\r\n afterRedraw = [];\r\n\r\n setAnimation(animation, chart);\r\n\r\n if (isHiddenChart) {\r\n chart.cloneRenderTo();\r\n }\r\n\r\n // Adjust title layout (reflow multiline text)\r\n chart.layOutTitles();\r\n\r\n // link stacked series\r\n while (i--) {\r\n serie = series[i];\r\n\r\n if (serie.options.stacking) {\r\n hasStackedSeries = true;\r\n\r\n if (serie.isDirty) {\r\n hasDirtyStacks = true;\r\n break;\r\n }\r\n }\r\n }\r\n if (hasDirtyStacks) {\r\n // mark others as dirty\r\n i = seriesLength;\r\n while (i--) {\r\n serie = series[i];\r\n if (serie.options.stacking) {\r\n serie.isDirty = true;\r\n }\r\n }\r\n }\r\n\r\n // handle updated data in the series\r\n each(series, function(serie) {\r\n if (serie.isDirty) {\r\n // prepare the data so axis can read it\r\n if (serie.options.legendType === \"point\") {\r\n redrawLegend = true;\r\n }\r\n }\r\n });\r\n\r\n // handle added or removed series\r\n if (redrawLegend && legend.options.enabled) {\r\n // series or pie points are added or removed\r\n // draw legend graphics\r\n legend.render();\r\n\r\n chart.isDirtyLegend = false;\r\n }\r\n\r\n // reset stacks\r\n if (hasStackedSeries) {\r\n chart.getStacks();\r\n }\r\n\r\n if (chart.hasCartesianSeries) {\r\n if (!chart.isResizing) {\r\n // reset maxTicks\r\n chart.maxTicks = null;\r\n\r\n // set axes scales\r\n each(axes, function(axis) {\r\n axis.setScale();\r\n });\r\n }\r\n\r\n chart.adjustTickAmounts();\r\n chart.getMargins();\r\n\r\n // If one axis is dirty, all axes must be redrawn (#792, #2169)\r\n each(axes, function(axis) {\r\n if (axis.isDirty) {\r\n isDirtyBox = true;\r\n }\r\n });\r\n\r\n // redraw axes\r\n each(axes, function(axis) {\r\n // Fire 'afterSetExtremes' only if extremes are set\r\n if (axis.isDirtyExtremes) {\r\n // #821\r\n axis.isDirtyExtremes = false;\r\n afterRedraw.push(function() {\r\n // prevent a recursive call to chart.redraw() (#1119)\r\n fireEvent(\r\n axis,\r\n \"afterSetExtremes\",\r\n extend(axis.eventArgs, axis.getExtremes())\r\n ); // #747, #751\r\n delete axis.eventArgs;\r\n });\r\n }\r\n\r\n if (isDirtyBox || hasStackedSeries) {\r\n axis.redraw();\r\n }\r\n });\r\n }\r\n // the plot areas size has changed\r\n if (isDirtyBox) {\r\n chart.drawChartBox();\r\n }\r\n\r\n // redraw affected series\r\n each(series, function(serie) {\r\n if (\r\n serie.isDirty &&\r\n serie.visible &&\r\n (!serie.isCartesian || serie.xAxis)\r\n ) {\r\n // issue #153\r\n serie.redraw();\r\n }\r\n });\r\n\r\n // move tooltip or reset\r\n if (pointer && pointer.reset) {\r\n pointer.reset(true);\r\n }\r\n\r\n // redraw if canvas\r\n renderer.draw();\r\n\r\n // fire the event\r\n fireEvent(chart, \"redraw\"); // jQuery breaks this when calling it from addEvent. Overwrites chart.redraw\r\n\r\n if (isHiddenChart) {\r\n chart.cloneRenderTo(true);\r\n }\r\n\r\n // Fire callbacks that are put on hold until after the redraw\r\n each(afterRedraw, function(callback) {\r\n callback.call();\r\n });\r\n },\r\n\r\n /**\r\n * Dim the chart and show a loading text or symbol\r\n * @param {String} str An optional text to show in the loading label instead of the default one\r\n */\r\n showLoading: function(str) {\r\n var chart = this,\r\n options = chart.options,\r\n loadingDiv = chart.loadingDiv;\r\n\r\n var loadingOptions = options.loading;\r\n\r\n // create the layer at the first call\r\n if (!loadingDiv) {\r\n chart.loadingDiv = loadingDiv = createElement(\r\n DIV,\r\n {\r\n className: PREFIX + \"loading\"\r\n },\r\n extend(loadingOptions.style, {\r\n zIndex: 10,\r\n display: NONE\r\n }),\r\n chart.container\r\n );\r\n\r\n chart.loadingSpan = createElement(\r\n \"span\",\r\n null,\r\n loadingOptions.labelStyle,\r\n loadingDiv\r\n );\r\n }\r\n\r\n // update text\r\n chart.loadingSpan.innerHTML = str || options.lang.loading;\r\n\r\n // show it\r\n if (!chart.loadingShown) {\r\n css(loadingDiv, {\r\n opacity: 0,\r\n display: \"\",\r\n left: chart.plotLeft + PX,\r\n top: chart.plotTop + PX,\r\n width: chart.plotWidth + PX,\r\n height: chart.plotHeight + PX\r\n });\r\n animate(\r\n loadingDiv,\r\n {\r\n opacity: loadingOptions.style.opacity\r\n },\r\n {\r\n duration: loadingOptions.showDuration || 0\r\n }\r\n );\r\n chart.loadingShown = true;\r\n }\r\n },\r\n\r\n /**\r\n * Hide the loading layer\r\n */\r\n hideLoading: function() {\r\n var options = this.options,\r\n loadingDiv = this.loadingDiv;\r\n\r\n if (loadingDiv) {\r\n animate(\r\n loadingDiv,\r\n {\r\n opacity: 0\r\n },\r\n {\r\n duration: options.loading.hideDuration || 100,\r\n complete: function() {\r\n css(loadingDiv, { display: NONE });\r\n }\r\n }\r\n );\r\n }\r\n this.loadingShown = false;\r\n },\r\n\r\n /**\r\n * Get an axis, series or point object by id.\r\n * @param id {String} The id as given in the configuration options\r\n */\r\n get: function(id) {\r\n var chart = this,\r\n axes = chart.axes,\r\n series = chart.series;\r\n\r\n var i, j, points;\r\n\r\n // search axes\r\n for (i = 0; i < axes.length; i++) {\r\n if (axes[i].options.id === id) {\r\n return axes[i];\r\n }\r\n }\r\n\r\n // search series\r\n for (i = 0; i < series.length; i++) {\r\n if (series[i].options.id === id) {\r\n return series[i];\r\n }\r\n }\r\n\r\n // search points\r\n for (i = 0; i < series.length; i++) {\r\n points = series[i].points || [];\r\n for (j = 0; j < points.length; j++) {\r\n if (points[j].id === id) {\r\n return points[j];\r\n }\r\n }\r\n }\r\n return null;\r\n },\r\n\r\n /**\r\n * Create the Axis instances based on the config options\r\n */\r\n getAxes: function() {\r\n var chart = this,\r\n options = this.options,\r\n xAxisOptions = (options.xAxis = splat(options.xAxis || {})),\r\n yAxisOptions = (options.yAxis = splat(options.yAxis || {})),\r\n optionsArray,\r\n axis;\r\n\r\n // make sure the options are arrays and add some members\r\n each(xAxisOptions, function(axis, i) {\r\n axis.index = i;\r\n axis.isX = true;\r\n });\r\n\r\n each(yAxisOptions, function(axis, i) {\r\n axis.index = i;\r\n });\r\n\r\n // concatenate all axis options into one array\r\n optionsArray = xAxisOptions.concat(yAxisOptions);\r\n\r\n each(optionsArray, function(axisOptions) {\r\n axis = new Axis(chart, axisOptions);\r\n });\r\n\r\n chart.adjustTickAmounts();\r\n },\r\n\r\n /**\r\n * Get the currently selected points from all series\r\n */\r\n getSelectedPoints: function() {\r\n var points = [];\r\n each(this.series, function(serie) {\r\n points = points.concat(\r\n grep(serie.points || [], function(point) {\r\n return point.selected;\r\n })\r\n );\r\n });\r\n return points;\r\n },\r\n\r\n /**\r\n * Get the currently selected series\r\n */\r\n getSelectedSeries: function() {\r\n return grep(this.series, function(serie) {\r\n return serie.selected;\r\n });\r\n },\r\n\r\n /**\r\n * Generate stacks for each series and calculate stacks total values\r\n */\r\n getStacks: function() {\r\n var chart = this;\r\n\r\n // reset stacks for each yAxis\r\n each(chart.yAxis, function(axis) {\r\n if (axis.stacks && axis.hasVisibleSeries) {\r\n axis.oldStacks = axis.stacks;\r\n }\r\n });\r\n\r\n each(chart.series, function(series) {\r\n if (\r\n series.options.stacking &&\r\n (series.visible === true ||\r\n chart.options.chart.ignoreHiddenSeries === false)\r\n ) {\r\n series.stackKey = series.type + pick(series.options.stack, \"\");\r\n }\r\n });\r\n },\r\n\r\n /**\r\n * Display the zoom button\r\n */\r\n showResetZoom: function() {\r\n var chart = this,\r\n lang = defaultOptions.lang,\r\n btnOptions = chart.options.chart.resetZoomButton,\r\n theme = btnOptions.theme,\r\n states = theme.states,\r\n alignTo = btnOptions.relativeTo === \"chart\" ? null : \"plotBox\";\r\n\r\n this.resetZoomButton = chart.renderer\r\n .button(\r\n lang.resetZoom,\r\n null,\r\n null,\r\n function() {\r\n chart.zoomOut();\r\n },\r\n theme,\r\n states && states.hover\r\n )\r\n .attr({\r\n align: btnOptions.position.align,\r\n title: lang.resetZoomTitle\r\n })\r\n .add()\r\n .align(btnOptions.position, false, alignTo);\r\n },\r\n\r\n /**\r\n * Zoom out to 1:1\r\n */\r\n zoomOut: function() {\r\n var chart = this;\r\n fireEvent(chart, \"selection\", { resetSelection: true }, function() {\r\n chart.zoom();\r\n });\r\n },\r\n\r\n /**\r\n * Zoom into a given portion of the chart given by axis coordinates\r\n * @param {Object} event\r\n */\r\n zoom: function(event) {\r\n var chart = this,\r\n hasZoomed,\r\n pointer = chart.pointer,\r\n displayButton = false,\r\n resetZoomButton;\r\n\r\n // If zoom is called with no arguments, reset the axes\r\n if (!event || event.resetSelection) {\r\n each(chart.axes, function(axis) {\r\n hasZoomed = axis.zoom();\r\n });\r\n }\r\n else {\r\n // else, zoom in on all axes\r\n each(event.xAxis.concat(event.yAxis), function(axisData) {\r\n var axis = axisData.axis,\r\n isXAxis = axis.isXAxis;\r\n\r\n // don't zoom more than minRange\r\n if (\r\n pointer[isXAxis ? \"zoomX\" : \"zoomY\"] ||\r\n pointer[isXAxis ? \"pinchX\" : \"pinchY\"]\r\n ) {\r\n hasZoomed = axis.zoom(axisData.min, axisData.max);\r\n if (axis.displayBtn) {\r\n displayButton = true;\r\n }\r\n }\r\n });\r\n }\r\n\r\n // Show or hide the Reset zoom button\r\n resetZoomButton = chart.resetZoomButton;\r\n if (displayButton && !resetZoomButton) {\r\n chart.showResetZoom();\r\n }\r\n else if (!displayButton && isObject(resetZoomButton)) {\r\n chart.resetZoomButton = resetZoomButton.destroy();\r\n }\r\n\r\n // Redraw\r\n if (hasZoomed) {\r\n chart.redraw(\r\n pick(\r\n chart.options.chart.animation,\r\n event && event.animation,\r\n chart.pointCount < 100\r\n ) // animation\r\n );\r\n }\r\n },\r\n\r\n /**\r\n * Pan the chart by dragging the mouse across the pane. This function is called\r\n * on mouse move, and the distance to pan is computed from chartX compared to\r\n * the first chartX position in the dragging operation.\r\n */\r\n pan: function(e, panning) {\r\n var chart = this,\r\n hoverPoints = chart.hoverPoints,\r\n doRedraw;\r\n\r\n // remove active points for shared tooltip\r\n if (hoverPoints) {\r\n each(hoverPoints, function(point) {\r\n point.setState();\r\n });\r\n }\r\n\r\n each(panning === \"xy\" ? [1, 0] : [1], function(isX) {\r\n // xy is used in maps\r\n var mousePos = e[isX ? \"chartX\" : \"chartY\"],\r\n axis = chart[isX ? \"xAxis\" : \"yAxis\"][0],\r\n startPos = chart[isX ? \"mouseDownX\" : \"mouseDownY\"],\r\n halfPointRange = (axis.pointRange || 0) / 2,\r\n extremes = axis.getExtremes(),\r\n newMin = axis.toValue(startPos - mousePos, true) + halfPointRange,\r\n newMax =\r\n axis.toValue(\r\n startPos + chart[isX ? \"plotWidth\" : \"plotHeight\"] - mousePos,\r\n true\r\n ) - halfPointRange;\r\n\r\n if (\r\n axis.series.length &&\r\n newMin > mathMin(extremes.dataMin, extremes.min) &&\r\n newMax < mathMax(extremes.dataMax, extremes.max)\r\n ) {\r\n axis.setExtremes(newMin, newMax, false, false, { trigger: \"pan\" });\r\n doRedraw = true;\r\n }\r\n\r\n chart[isX ? \"mouseDownX\" : \"mouseDownY\"] = mousePos; // set new reference for next run\r\n });\r\n\r\n if (doRedraw) {\r\n chart.redraw(false);\r\n }\r\n css(chart.container, { cursor: \"move\" });\r\n },\r\n\r\n /**\r\n * Show the title and subtitle of the chart\r\n *\r\n * @param titleOptions {Object} New title options\r\n * @param subtitleOptions {Object} New subtitle options\r\n *\r\n */\r\n setTitle: function(titleOptions, subtitleOptions) {\r\n var chart = this,\r\n options = chart.options,\r\n chartTitleOptions,\r\n chartSubtitleOptions;\r\n\r\n chartTitleOptions = options.title = merge(options.title, titleOptions);\r\n chartSubtitleOptions = options.subtitle = merge(\r\n options.subtitle,\r\n subtitleOptions\r\n );\r\n\r\n // add title and subtitle\r\n each(\r\n [\r\n [\"title\", titleOptions, chartTitleOptions],\r\n [\"subtitle\", subtitleOptions, chartSubtitleOptions]\r\n ],\r\n function(arr) {\r\n var name = arr[0],\r\n title = chart[name],\r\n titleOptions = arr[1],\r\n chartTitleOptions = arr[2];\r\n\r\n if (title && titleOptions) {\r\n chart[name] = title = title.destroy(); // remove old\r\n }\r\n\r\n if (chartTitleOptions && chartTitleOptions.text && !title) {\r\n chart[name] = chart.renderer\r\n .text(chartTitleOptions.text, 0, 0, chartTitleOptions.useHTML)\r\n .attr({\r\n align: chartTitleOptions.align,\r\n class: PREFIX + name,\r\n zIndex: chartTitleOptions.zIndex || 4\r\n })\r\n .css(chartTitleOptions.style)\r\n .add();\r\n }\r\n }\r\n );\r\n chart.layOutTitles();\r\n },\r\n\r\n /**\r\n * Lay out the chart titles and cache the full offset height for use in getMargins\r\n */\r\n layOutTitles: function() {\r\n var titleOffset = 0,\r\n title = this.title,\r\n subtitle = this.subtitle,\r\n options = this.options,\r\n titleOptions = options.title,\r\n subtitleOptions = options.subtitle,\r\n autoWidth = this.spacingBox.width - 44; // 44 makes room for default context button\r\n\r\n if (title) {\r\n title\r\n .css({ width: (titleOptions.width || autoWidth) + PX })\r\n .align(extend({ y: 15 }, titleOptions), false, \"spacingBox\");\r\n\r\n if (!titleOptions.floating && !titleOptions.verticalAlign) {\r\n titleOffset = title.getBBox().height;\r\n\r\n // Adjust for browser consistency + backwards compat after #776 fix\r\n if (titleOffset >= 18 && titleOffset <= 25) {\r\n titleOffset = 15;\r\n }\r\n }\r\n }\r\n if (subtitle) {\r\n subtitle\r\n .css({ width: (subtitleOptions.width || autoWidth) + PX })\r\n .align(\r\n extend({ y: titleOffset + titleOptions.margin }, subtitleOptions),\r\n false,\r\n \"spacingBox\"\r\n );\r\n\r\n if (!subtitleOptions.floating && !subtitleOptions.verticalAlign) {\r\n titleOffset = mathCeil(titleOffset + subtitle.getBBox().height);\r\n }\r\n }\r\n\r\n this.titleOffset = titleOffset; // used in getMargins\r\n },\r\n\r\n /**\r\n * Get chart width and height according to options and container size\r\n */\r\n getChartSize: function() {\r\n var chart = this,\r\n optionsChart = chart.options.chart,\r\n renderTo = chart.renderToClone || chart.renderTo;\r\n\r\n // get inner width and height from jQuery (#824)\r\n chart.containerWidth = adapterRun(renderTo, \"width\");\r\n chart.containerHeight = adapterRun(renderTo, \"height\");\r\n\r\n chart.chartWidth = mathMax(\r\n 0,\r\n optionsChart.width || chart.containerWidth || 600\r\n ); // #1393, 1460\r\n chart.chartHeight = mathMax(\r\n 0,\r\n pick(\r\n optionsChart.height,\r\n // the offsetHeight of an empty container is 0 in standard browsers, but 19 in IE7:\r\n chart.containerHeight > 19 ? chart.containerHeight : 400\r\n )\r\n );\r\n },\r\n\r\n /**\r\n * Create a clone of the chart's renderTo div and place it outside the viewport to allow\r\n * size computation on chart.render and chart.redraw\r\n */\r\n cloneRenderTo: function(revert) {\r\n var clone = this.renderToClone,\r\n container = this.container;\r\n\r\n // Destroy the clone and bring the container back to the real renderTo div\r\n if (revert) {\r\n if (clone) {\r\n this.renderTo.appendChild(container);\r\n discardElement(clone);\r\n delete this.renderToClone;\r\n }\r\n\r\n // Set up the clone\r\n }\r\n else {\r\n if (container && container.parentNode === this.renderTo) {\r\n this.renderTo.removeChild(container); // do not clone this\r\n }\r\n this.renderToClone = clone = this.renderTo.cloneNode(0);\r\n css(clone, {\r\n position: ABSOLUTE,\r\n top: \"-9999px\",\r\n display: \"block\" // #833\r\n });\r\n doc.body.appendChild(clone);\r\n if (container) {\r\n clone.appendChild(container);\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Get the containing element, determine the size and create the inner container\r\n * div to hold the chart\r\n */\r\n getContainer: function() {\r\n var chart = this,\r\n container,\r\n optionsChart = chart.options.chart,\r\n chartWidth,\r\n chartHeight,\r\n renderTo,\r\n indexAttrName = \"data-highcharts-chart\",\r\n oldChartIndex,\r\n containerId;\r\n\r\n chart.renderTo = renderTo = optionsChart.renderTo;\r\n containerId = PREFIX + idCounter++;\r\n\r\n if (isString(renderTo)) {\r\n chart.renderTo = renderTo = doc.getElementById(renderTo);\r\n }\r\n\r\n // Display an error if the renderTo is wrong\r\n if (!renderTo) {\r\n error(13, true);\r\n }\r\n\r\n // If the container already holds a chart, destroy it\r\n oldChartIndex = pInt(attr(renderTo, indexAttrName));\r\n if (!isNaN(oldChartIndex) && charts[oldChartIndex]) {\r\n charts[oldChartIndex].destroy();\r\n }\r\n\r\n // Make a reference to the chart from the div\r\n attr(renderTo, indexAttrName, chart.index);\r\n\r\n // remove previous chart\r\n renderTo.innerHTML = \"\";\r\n\r\n // If the container doesn't have an offsetWidth, it has or is a child of a node\r\n // that has display:none. We need to temporarily move it out to a visible\r\n // state to determine the size, else the legend and tooltips won't render\r\n // properly\r\n if (!renderTo.offsetWidth) {\r\n chart.cloneRenderTo();\r\n }\r\n\r\n // get the width and height\r\n chart.getChartSize();\r\n chartWidth = chart.chartWidth;\r\n chartHeight = chart.chartHeight;\r\n\r\n // create the inner container\r\n chart.container = container = createElement(\r\n DIV,\r\n {\r\n className:\r\n PREFIX +\r\n \"container\" +\r\n (optionsChart.className ? \" \" + optionsChart.className : \"\"),\r\n id: containerId\r\n },\r\n extend(\r\n {\r\n position: RELATIVE,\r\n overflow: HIDDEN, // needed for context menu (avoid scrollbars) and\r\n // content overflow in IE\r\n width: chartWidth + PX,\r\n height: chartHeight + PX,\r\n textAlign: \"left\",\r\n lineHeight: \"normal\", // #427\r\n zIndex: 0, // #1072\r\n \"-webkit-tap-highlight-color\": \"rgba(0,0,0,0)\"\r\n },\r\n optionsChart.style\r\n ),\r\n chart.renderToClone || renderTo\r\n );\r\n\r\n // cache the cursor (#1650)\r\n chart._cursor = container.style.cursor;\r\n\r\n chart.renderer = optionsChart.forExport // force SVG, used for SVG export\r\n ? new SVGRenderer(container, chartWidth, chartHeight, true)\r\n : new Renderer(container, chartWidth, chartHeight);\r\n\r\n if (useCanVG) {\r\n // If we need canvg library, extend and configure the renderer\r\n // to get the tracker for translating mouse events\r\n chart.renderer.create(chart, container, chartWidth, chartHeight);\r\n }\r\n },\r\n\r\n /**\r\n * Calculate margins by rendering axis labels in a preliminary position. Title,\r\n * subtitle and legend have already been rendered at this stage, but will be\r\n * moved into their final positions\r\n */\r\n getMargins: function() {\r\n var chart = this,\r\n spacing = chart.spacing,\r\n axisOffset,\r\n legend = chart.legend,\r\n margin = chart.margin,\r\n legendOptions = chart.options.legend,\r\n legendMargin = pick(legendOptions.margin, 10),\r\n legendX = legendOptions.x,\r\n legendY = legendOptions.y,\r\n align = legendOptions.align,\r\n verticalAlign = legendOptions.verticalAlign,\r\n titleOffset = chart.titleOffset;\r\n\r\n chart.resetMargins();\r\n axisOffset = chart.axisOffset;\r\n\r\n // Adjust for title and subtitle\r\n if (titleOffset && !defined(margin[0])) {\r\n chart.plotTop = mathMax(\r\n chart.plotTop,\r\n titleOffset + chart.options.title.margin + spacing[0]\r\n );\r\n }\r\n\r\n // Adjust for legend\r\n if (legend.display && !legendOptions.floating) {\r\n if (align === \"right\") {\r\n // horizontal alignment handled first\r\n if (!defined(margin[1])) {\r\n chart.marginRight = mathMax(\r\n chart.marginRight,\r\n legend.legendWidth - legendX + legendMargin + spacing[1]\r\n );\r\n }\r\n }\r\n else if (align === \"left\") {\r\n if (!defined(margin[3])) {\r\n chart.plotLeft = mathMax(\r\n chart.plotLeft,\r\n legend.legendWidth + legendX + legendMargin + spacing[3]\r\n );\r\n }\r\n }\r\n else if (verticalAlign === \"top\") {\r\n if (!defined(margin[0])) {\r\n chart.plotTop = mathMax(\r\n chart.plotTop,\r\n legend.legendHeight + legendY + legendMargin + spacing[0]\r\n );\r\n }\r\n }\r\n else if (verticalAlign === \"bottom\") {\r\n if (!defined(margin[2])) {\r\n chart.marginBottom = mathMax(\r\n chart.marginBottom,\r\n legend.legendHeight - legendY + legendMargin + spacing[2]\r\n );\r\n }\r\n }\r\n }\r\n\r\n // adjust for scroller\r\n if (chart.extraBottomMargin) {\r\n chart.marginBottom += chart.extraBottomMargin;\r\n }\r\n if (chart.extraTopMargin) {\r\n chart.plotTop += chart.extraTopMargin;\r\n }\r\n\r\n // pre-render axes to get labels offset width\r\n if (chart.hasCartesianSeries) {\r\n each(chart.axes, function(axis) {\r\n axis.getOffset();\r\n });\r\n }\r\n\r\n if (!defined(margin[3])) {\r\n chart.plotLeft += axisOffset[3];\r\n }\r\n if (!defined(margin[0])) {\r\n chart.plotTop += axisOffset[0];\r\n }\r\n if (!defined(margin[2])) {\r\n chart.marginBottom += axisOffset[2];\r\n }\r\n if (!defined(margin[1])) {\r\n chart.marginRight += axisOffset[1];\r\n }\r\n\r\n chart.setChartSize();\r\n },\r\n\r\n /**\r\n * Add the event handlers necessary for auto resizing\r\n *\r\n */\r\n initReflow: function() {\r\n var chart = this,\r\n optionsChart = chart.options.chart,\r\n renderTo = chart.renderTo,\r\n reflowTimeout;\r\n\r\n function reflow(e) {\r\n var width = optionsChart.width || adapterRun(renderTo, \"width\"),\r\n height = optionsChart.height || adapterRun(renderTo, \"height\"),\r\n target = e ? e.target : win; // #805 - MooTools doesn't supply e\r\n\r\n // Width and height checks for display:none. Target is doc in IE8 and Opera,\r\n // win in Firefox, Chrome and IE9.\r\n if (\r\n !chart.hasUserSize &&\r\n width &&\r\n height &&\r\n (target === win || target === doc)\r\n ) {\r\n if (\r\n width !== chart.containerWidth ||\r\n height !== chart.containerHeight\r\n ) {\r\n clearTimeout(reflowTimeout);\r\n chart.reflowTimeout = reflowTimeout = setTimeout(function() {\r\n if (chart.container) {\r\n // It may have been destroyed in the meantime (#1257)\r\n chart.setSize(width, height, false);\r\n chart.hasUserSize = null;\r\n }\r\n }, 100);\r\n }\r\n chart.containerWidth = width;\r\n chart.containerHeight = height;\r\n }\r\n }\r\n chart.reflow = reflow;\r\n addEvent(win, \"resize\", reflow);\r\n addEvent(chart, \"destroy\", function() {\r\n removeEvent(win, \"resize\", reflow);\r\n });\r\n },\r\n\r\n /**\r\n * Resize the chart to a given width and height\r\n * @param {Number} width\r\n * @param {Number} height\r\n * @param {Object|Boolean} animation\r\n */\r\n setSize: function(width, height, animation) {\r\n var chart = this,\r\n chartWidth,\r\n chartHeight,\r\n fireEndResize;\r\n\r\n // Handle the isResizing counter\r\n chart.isResizing += 1;\r\n fireEndResize = function() {\r\n if (chart) {\r\n fireEvent(chart, \"endResize\", null, function() {\r\n chart.isResizing -= 1;\r\n });\r\n }\r\n };\r\n\r\n // set the animation for the current process\r\n setAnimation(animation, chart);\r\n\r\n chart.oldChartHeight = chart.chartHeight;\r\n chart.oldChartWidth = chart.chartWidth;\r\n if (defined(width)) {\r\n chart.chartWidth = chartWidth = mathMax(0, mathRound(width));\r\n chart.hasUserSize = !!chartWidth;\r\n }\r\n if (defined(height)) {\r\n chart.chartHeight = chartHeight = mathMax(0, mathRound(height));\r\n }\r\n\r\n css(chart.container, {\r\n width: chartWidth + PX,\r\n height: chartHeight + PX\r\n });\r\n chart.setChartSize(true);\r\n chart.renderer.setSize(chartWidth, chartHeight, animation);\r\n\r\n // handle axes\r\n chart.maxTicks = null;\r\n each(chart.axes, function(axis) {\r\n axis.isDirty = true;\r\n axis.setScale();\r\n });\r\n\r\n // make sure non-cartesian series are also handled\r\n each(chart.series, function(serie) {\r\n serie.isDirty = true;\r\n });\r\n\r\n chart.isDirtyLegend = true; // force legend redraw\r\n chart.isDirtyBox = true; // force redraw of plot and chart border\r\n\r\n chart.getMargins();\r\n\r\n chart.redraw(animation);\r\n\r\n chart.oldChartHeight = null;\r\n fireEvent(chart, \"resize\");\r\n\r\n // fire endResize and set isResizing back\r\n // If animation is disabled, fire without delay\r\n if (globalAnimation === false) {\r\n fireEndResize();\r\n }\r\n else {\r\n // else set a timeout with the animation duration\r\n setTimeout(\r\n fireEndResize,\r\n (globalAnimation && globalAnimation.duration) || 500\r\n );\r\n }\r\n },\r\n\r\n /**\r\n * Set the public chart properties. This is done before and after the pre-render\r\n * to determine margin sizes\r\n */\r\n setChartSize: function(skipAxes) {\r\n var chart = this,\r\n inverted = chart.inverted,\r\n renderer = chart.renderer,\r\n chartWidth = chart.chartWidth,\r\n chartHeight = chart.chartHeight,\r\n optionsChart = chart.options.chart,\r\n spacing = chart.spacing,\r\n clipOffset = chart.clipOffset,\r\n clipX,\r\n clipY,\r\n plotLeft,\r\n plotTop,\r\n plotWidth,\r\n plotHeight,\r\n plotBorderWidth;\r\n\r\n chart.plotLeft = plotLeft = mathRound(chart.plotLeft);\r\n chart.plotTop = plotTop = mathRound(chart.plotTop);\r\n chart.plotWidth = plotWidth = mathMax(\r\n 0,\r\n mathRound(chartWidth - plotLeft - chart.marginRight)\r\n );\r\n chart.plotHeight = plotHeight = mathMax(\r\n 0,\r\n mathRound(chartHeight - plotTop - chart.marginBottom)\r\n );\r\n\r\n chart.plotSizeX = inverted ? plotHeight : plotWidth;\r\n chart.plotSizeY = inverted ? plotWidth : plotHeight;\r\n\r\n chart.plotBorderWidth = optionsChart.plotBorderWidth || 0;\r\n\r\n // Set boxes used for alignment\r\n chart.spacingBox = renderer.spacingBox = {\r\n x: spacing[3],\r\n y: spacing[0],\r\n width: chartWidth - spacing[3] - spacing[1],\r\n height: chartHeight - spacing[0] - spacing[2]\r\n };\r\n chart.plotBox = renderer.plotBox = {\r\n x: plotLeft,\r\n y: plotTop,\r\n width: plotWidth,\r\n height: plotHeight\r\n };\r\n\r\n plotBorderWidth = 2 * mathFloor(chart.plotBorderWidth / 2);\r\n clipX = mathCeil(mathMax(plotBorderWidth, clipOffset[3]) / 2);\r\n clipY = mathCeil(mathMax(plotBorderWidth, clipOffset[0]) / 2);\r\n chart.clipBox = {\r\n x: clipX,\r\n y: clipY,\r\n width: mathFloor(\r\n chart.plotSizeX - mathMax(plotBorderWidth, clipOffset[1]) / 2 - clipX\r\n ),\r\n height: mathFloor(\r\n chart.plotSizeY - mathMax(plotBorderWidth, clipOffset[2]) / 2 - clipY\r\n )\r\n };\r\n\r\n if (!skipAxes) {\r\n each(chart.axes, function(axis) {\r\n axis.setAxisSize();\r\n axis.setAxisTranslation();\r\n });\r\n }\r\n },\r\n\r\n /**\r\n * Initial margins before auto size margins are applied\r\n */\r\n resetMargins: function() {\r\n var chart = this,\r\n spacing = chart.spacing,\r\n margin = chart.margin;\r\n\r\n chart.plotTop = pick(margin[0], spacing[0]);\r\n chart.marginRight = pick(margin[1], spacing[1]);\r\n chart.marginBottom = pick(margin[2], spacing[2]);\r\n chart.plotLeft = pick(margin[3], spacing[3]);\r\n chart.axisOffset = [0, 0, 0, 0]; // top, right, bottom, left\r\n chart.clipOffset = [0, 0, 0, 0];\r\n },\r\n\r\n /**\r\n * Draw the borders and backgrounds for chart and plot area\r\n */\r\n drawChartBox: function() {\r\n var chart = this,\r\n optionsChart = chart.options.chart,\r\n renderer = chart.renderer,\r\n chartWidth = chart.chartWidth,\r\n chartHeight = chart.chartHeight,\r\n chartBackground = chart.chartBackground,\r\n plotBackground = chart.plotBackground,\r\n plotBorder = chart.plotBorder,\r\n plotBGImage = chart.plotBGImage,\r\n chartBorderWidth = optionsChart.borderWidth || 0,\r\n chartBackgroundColor = optionsChart.backgroundColor,\r\n plotBackgroundColor = optionsChart.plotBackgroundColor,\r\n plotBackgroundImage = optionsChart.plotBackgroundImage,\r\n plotBorderWidth = optionsChart.plotBorderWidth || 0,\r\n mgn,\r\n bgAttr,\r\n plotLeft = chart.plotLeft,\r\n plotTop = chart.plotTop,\r\n plotWidth = chart.plotWidth,\r\n plotHeight = chart.plotHeight,\r\n plotBox = chart.plotBox,\r\n clipRect = chart.clipRect,\r\n clipBox = chart.clipBox;\r\n\r\n // Chart area\r\n mgn = chartBorderWidth + (optionsChart.shadow ? 8 : 0);\r\n\r\n if (chartBorderWidth || chartBackgroundColor) {\r\n if (!chartBackground) {\r\n bgAttr = {\r\n fill: chartBackgroundColor || NONE\r\n };\r\n if (chartBorderWidth) {\r\n // #980\r\n bgAttr.stroke = optionsChart.borderColor;\r\n bgAttr[\"stroke-width\"] = chartBorderWidth;\r\n }\r\n chart.chartBackground = renderer\r\n .rect(\r\n mgn / 2,\r\n mgn / 2,\r\n chartWidth - mgn,\r\n chartHeight - mgn,\r\n optionsChart.borderRadius,\r\n chartBorderWidth\r\n )\r\n .attr(bgAttr)\r\n .add()\r\n .shadow(optionsChart.shadow);\r\n }\r\n else {\r\n // resize\r\n chartBackground.animate(\r\n chartBackground.crisp(\r\n null,\r\n null,\r\n null,\r\n chartWidth - mgn,\r\n chartHeight - mgn\r\n )\r\n );\r\n }\r\n }\r\n\r\n // Plot background\r\n if (plotBackgroundColor) {\r\n if (!plotBackground) {\r\n chart.plotBackground = renderer\r\n .rect(plotLeft, plotTop, plotWidth, plotHeight, 0)\r\n .attr({\r\n fill: plotBackgroundColor\r\n })\r\n .add()\r\n .shadow(optionsChart.plotShadow);\r\n }\r\n else {\r\n plotBackground.animate(plotBox);\r\n }\r\n }\r\n if (plotBackgroundImage) {\r\n if (!plotBGImage) {\r\n chart.plotBGImage = renderer\r\n .image(\r\n plotBackgroundImage,\r\n plotLeft,\r\n plotTop,\r\n plotWidth,\r\n plotHeight\r\n )\r\n .add();\r\n }\r\n else {\r\n plotBGImage.animate(plotBox);\r\n }\r\n }\r\n\r\n // Plot clip\r\n if (!clipRect) {\r\n chart.clipRect = renderer.clipRect(clipBox);\r\n }\r\n else {\r\n clipRect.animate({\r\n width: clipBox.width,\r\n height: clipBox.height\r\n });\r\n }\r\n\r\n // Plot area border\r\n if (plotBorderWidth) {\r\n if (!plotBorder) {\r\n chart.plotBorder = renderer\r\n .rect(plotLeft, plotTop, plotWidth, plotHeight, 0, -plotBorderWidth)\r\n .attr({\r\n stroke: optionsChart.plotBorderColor,\r\n \"stroke-width\": plotBorderWidth,\r\n zIndex: 1\r\n })\r\n .add();\r\n }\r\n else {\r\n plotBorder.animate(\r\n plotBorder.crisp(null, plotLeft, plotTop, plotWidth, plotHeight)\r\n );\r\n }\r\n }\r\n\r\n // reset\r\n chart.isDirtyBox = false;\r\n },\r\n\r\n /**\r\n * Detect whether a certain chart property is needed based on inspecting its options\r\n * and series. This mainly applies to the chart.invert property, and in extensions to\r\n * the chart.angular and chart.polar properties.\r\n */\r\n propFromSeries: function() {\r\n var chart = this,\r\n optionsChart = chart.options.chart,\r\n klass,\r\n seriesOptions = chart.options.series,\r\n i,\r\n value;\r\n\r\n each([\"inverted\", \"angular\", \"polar\"], function(key) {\r\n // The default series type's class\r\n klass =\r\n seriesTypes[optionsChart.type || optionsChart.defaultSeriesType];\r\n\r\n // Get the value from available chart-wide properties\r\n value =\r\n chart[key] || // 1. it is set before\r\n optionsChart[key] || // 2. it is set in the options\r\n (klass && klass.prototype[key]); // 3. it's default series class requires it\r\n\r\n // 4. Check if any the chart's series require it\r\n i = seriesOptions && seriesOptions.length;\r\n while (!value && i--) {\r\n klass = seriesTypes[seriesOptions[i].type];\r\n if (klass && klass.prototype[key]) {\r\n value = true;\r\n }\r\n }\r\n\r\n // Set the chart property\r\n chart[key] = value;\r\n });\r\n },\r\n\r\n /**\r\n * Link two or more series together. This is done initially from Chart.render,\r\n * and after Chart.addSeries and Series.remove.\r\n */\r\n linkSeries: function() {\r\n var chart = this,\r\n chartSeries = chart.series;\r\n\r\n // Reset links\r\n each(chartSeries, function(series) {\r\n series.linkedSeries.length = 0;\r\n });\r\n\r\n // Apply new links\r\n each(chartSeries, function(series) {\r\n var linkedTo = series.options.linkedTo;\r\n if (isString(linkedTo)) {\r\n if (linkedTo === \":previous\") {\r\n linkedTo = chart.series[series.index - 1];\r\n }\r\n else {\r\n linkedTo = chart.get(linkedTo);\r\n }\r\n if (linkedTo) {\r\n linkedTo.linkedSeries.push(series);\r\n series.linkedParent = linkedTo;\r\n }\r\n }\r\n });\r\n },\r\n\r\n /**\r\n * Render all graphics for the chart\r\n */\r\n render: function() {\r\n var chart = this,\r\n axes = chart.axes,\r\n renderer = chart.renderer,\r\n options = chart.options;\r\n\r\n var labels = options.labels,\r\n credits = options.credits,\r\n creditsHref;\r\n\r\n // Title\r\n chart.setTitle();\r\n\r\n // Legend\r\n chart.legend = new Legend(chart, options.legend);\r\n\r\n chart.getStacks(); // render stacks\r\n\r\n // Get margins by pre-rendering axes\r\n // set axes scales\r\n each(axes, function(axis) {\r\n axis.setScale();\r\n });\r\n\r\n chart.getMargins();\r\n\r\n chart.maxTicks = null; // reset for second pass\r\n each(axes, function(axis) {\r\n axis.setTickPositions(true); // update to reflect the new margins\r\n axis.setMaxTicks();\r\n });\r\n chart.adjustTickAmounts();\r\n chart.getMargins(); // second pass to check for new labels\r\n\r\n // Draw the borders and backgrounds\r\n chart.drawChartBox();\r\n\r\n // Axes\r\n if (chart.hasCartesianSeries) {\r\n each(axes, function(axis) {\r\n axis.render();\r\n });\r\n }\r\n\r\n // The series\r\n if (!chart.seriesGroup) {\r\n chart.seriesGroup = renderer\r\n .g(\"series-group\")\r\n .attr({ zIndex: 3 })\r\n .add();\r\n }\r\n each(chart.series, function(serie) {\r\n serie.translate();\r\n serie.setTooltipPoints();\r\n serie.render();\r\n });\r\n\r\n // Labels\r\n if (labels.items) {\r\n each(labels.items, function(label) {\r\n var style = extend(labels.style, label.style),\r\n x = pInt(style.left) + chart.plotLeft,\r\n y = pInt(style.top) + chart.plotTop + 12;\r\n\r\n // delete to prevent rewriting in IE\r\n delete style.left;\r\n delete style.top;\r\n\r\n renderer\r\n .text(label.html, x, y)\r\n .attr({ zIndex: 2 })\r\n .css(style)\r\n .add();\r\n });\r\n }\r\n\r\n // Credits\r\n if (credits.enabled && !chart.credits) {\r\n creditsHref = credits.href;\r\n chart.credits = renderer\r\n .text(credits.text, 0, 0)\r\n .on(\"click\", function() {\r\n if (creditsHref) {\r\n location.href = creditsHref;\r\n }\r\n })\r\n .attr({\r\n align: credits.position.align,\r\n zIndex: 8\r\n })\r\n .css(credits.style)\r\n .add()\r\n .align(credits.position);\r\n }\r\n\r\n // Set flag\r\n chart.hasRendered = true;\r\n },\r\n\r\n /**\r\n * Clean up memory usage\r\n */\r\n destroy: function() {\r\n var chart = this,\r\n axes = chart.axes,\r\n series = chart.series,\r\n container = chart.container,\r\n i,\r\n parentNode = container && container.parentNode;\r\n\r\n // fire the chart.destoy event\r\n fireEvent(chart, \"destroy\");\r\n\r\n // Delete the chart from charts lookup array\r\n charts[chart.index] = UNDEFINED;\r\n chart.renderTo.removeAttribute(\"data-highcharts-chart\");\r\n\r\n // remove events\r\n removeEvent(chart);\r\n\r\n // ==== Destroy collections:\r\n // Destroy axes\r\n i = axes.length;\r\n while (i--) {\r\n axes[i] = axes[i].destroy();\r\n }\r\n\r\n // Destroy each series\r\n i = series.length;\r\n while (i--) {\r\n series[i] = series[i].destroy();\r\n }\r\n\r\n // ==== Destroy chart properties:\r\n each(\r\n [\r\n \"title\",\r\n \"subtitle\",\r\n \"chartBackground\",\r\n \"plotBackground\",\r\n \"plotBGImage\",\r\n \"plotBorder\",\r\n \"seriesGroup\",\r\n \"clipRect\",\r\n \"credits\",\r\n \"pointer\",\r\n \"scroller\",\r\n \"rangeSelector\",\r\n \"legend\",\r\n \"resetZoomButton\",\r\n \"tooltip\",\r\n \"renderer\"\r\n ],\r\n function(name) {\r\n var prop = chart[name];\r\n\r\n if (prop && prop.destroy) {\r\n chart[name] = prop.destroy();\r\n }\r\n }\r\n );\r\n\r\n // remove container and all SVG\r\n if (container) {\r\n // can break in IE when destroyed before finished loading\r\n container.innerHTML = \"\";\r\n removeEvent(container);\r\n if (parentNode) {\r\n discardElement(container);\r\n }\r\n }\r\n\r\n // clean it all up\r\n for (i in chart) {\r\n delete chart[i];\r\n }\r\n },\r\n\r\n /**\r\n * VML namespaces can't be added until after complete. Listening\r\n * for Perini's doScroll hack is not enough.\r\n */\r\n isReadyToRender: function() {\r\n var chart = this;\r\n\r\n // Note: in spite of JSLint's complaints, win == win.top is required\r\n /*jslint eqeq: true*/\r\n if (\r\n (!hasSVG && (win == win.top && doc.readyState !== \"complete\")) ||\r\n (useCanVG && !win.canvg)\r\n ) {\r\n /*jslint eqeq: false*/\r\n if (useCanVG) {\r\n // Delay rendering until canvg library is downloaded and ready\r\n CanVGController.push(function() {\r\n chart.firstRender();\r\n }, chart.options.global.canvasToolsURL);\r\n }\r\n else {\r\n doc.attachEvent(\"onreadystatechange\", function() {\r\n doc.detachEvent(\"onreadystatechange\", chart.firstRender);\r\n if (doc.readyState === \"complete\") {\r\n chart.firstRender();\r\n }\r\n });\r\n }\r\n return false;\r\n }\r\n return true;\r\n },\r\n\r\n /**\r\n * Prepare for first rendering after all data are loaded\r\n */\r\n firstRender: function() {\r\n var chart = this,\r\n options = chart.options,\r\n callback = chart.callback;\r\n\r\n // Check whether the chart is ready to render\r\n if (!chart.isReadyToRender()) {\r\n return;\r\n }\r\n\r\n // Create the container\r\n chart.getContainer();\r\n\r\n // Run an early event after the container and renderer are established\r\n fireEvent(chart, \"init\");\r\n\r\n chart.resetMargins();\r\n chart.setChartSize();\r\n\r\n // Set the common chart properties (mainly invert) from the given series\r\n chart.propFromSeries();\r\n\r\n // get axes\r\n chart.getAxes();\r\n\r\n // Initialize the series\r\n each(options.series || [], function(serieOptions) {\r\n chart.initSeries(serieOptions);\r\n });\r\n\r\n chart.linkSeries();\r\n\r\n // Run an event after axes and series are initialized, but before render. At this stage,\r\n // the series data is indexed and cached in the xData and yData arrays, so we can access\r\n // those before rendering. Used in Highstock.\r\n fireEvent(chart, \"beforeRender\");\r\n\r\n // depends on inverted and on margins being set\r\n chart.pointer = new Pointer(chart, options);\r\n\r\n chart.render();\r\n\r\n // add canvas\r\n chart.renderer.draw();\r\n // run callbacks\r\n if (callback) {\r\n callback.apply(chart, [chart]);\r\n }\r\n each(chart.callbacks, function(fn) {\r\n fn.apply(chart, [chart]);\r\n });\r\n\r\n // If the chart was rendered outside the top container, put it back in\r\n chart.cloneRenderTo(true);\r\n\r\n fireEvent(chart, \"load\");\r\n },\r\n\r\n /**\r\n * Creates arrays for spacing and margin from given options.\r\n */\r\n splashArray: function(target, options) {\r\n var oVar = options[target],\r\n tArray = isObject(oVar) ? oVar : [oVar, oVar, oVar, oVar];\r\n\r\n return [\r\n pick(options[target + \"Top\"], tArray[0]),\r\n pick(options[target + \"Right\"], tArray[1]),\r\n pick(options[target + \"Bottom\"], tArray[2]),\r\n pick(options[target + \"Left\"], tArray[3])\r\n ];\r\n }\r\n }; // end Chart\r\n\r\n // Hook for exporting module\r\n Chart.prototype.callbacks = [];\r\n /**\r\n * The Point object and prototype. Inheritable and used as base for PiePoint\r\n */\r\n var Point = function() {};\r\n Point.prototype = {\r\n /**\r\n * Initialize the point\r\n * @param {Object} series The series object containing this point\r\n * @param {Object} options The data in either number, array or object format\r\n */\r\n init: function(series, options, x) {\r\n var point = this,\r\n colors;\r\n point.series = series;\r\n point.applyOptions(options, x);\r\n point.pointAttr = {};\r\n\r\n if (series.options.colorByPoint) {\r\n colors = series.options.colors || series.chart.options.colors;\r\n point.color = point.color || colors[series.colorCounter++];\r\n // loop back to zero\r\n if (series.colorCounter === colors.length) {\r\n series.colorCounter = 0;\r\n }\r\n }\r\n\r\n series.chart.pointCount++;\r\n return point;\r\n },\r\n /**\r\n * Apply the options containing the x and y data and possible some extra properties.\r\n * This is called on point init or from point.update.\r\n *\r\n * @param {Object} options\r\n */\r\n applyOptions: function(options, x) {\r\n var point = this,\r\n series = point.series,\r\n pointValKey = series.pointValKey;\r\n\r\n options = Point.prototype.optionsToObject.call(this, options);\r\n\r\n // copy options directly to point\r\n extend(point, options);\r\n point.options = point.options ? extend(point.options, options) : options;\r\n\r\n // For higher dimension series types. For instance, for ranges, point.y is mapped to point.low.\r\n if (pointValKey) {\r\n point.y = point[pointValKey];\r\n }\r\n\r\n // If no x is set by now, get auto incremented value. All points must have an\r\n // x value, however the y value can be null to create a gap in the series\r\n if (point.x === UNDEFINED && series) {\r\n point.x = x === UNDEFINED ? series.autoIncrement() : x;\r\n }\r\n\r\n return point;\r\n },\r\n\r\n /**\r\n * Transform number or array configs into objects\r\n */\r\n optionsToObject: function(options) {\r\n var ret = {},\r\n series = this.series,\r\n pointArrayMap = series.pointArrayMap || [\"y\"],\r\n valueCount = pointArrayMap.length,\r\n firstItemType,\r\n i = 0,\r\n j = 0;\r\n\r\n if (typeof options === \"number\" || options === null) {\r\n ret[pointArrayMap[0]] = options;\r\n }\r\n else if (isArray(options)) {\r\n // with leading x value\r\n if (options.length > valueCount) {\r\n firstItemType = typeof options[0];\r\n if (firstItemType === \"string\") {\r\n ret.name = options[0];\r\n }\r\n else if (firstItemType === \"number\") {\r\n ret.x = options[0];\r\n }\r\n i++;\r\n }\r\n while (j < valueCount) {\r\n ret[pointArrayMap[j++]] = options[i++];\r\n }\r\n }\r\n else if (typeof options === \"object\") {\r\n ret = options;\r\n\r\n // This is the fastest way to detect if there are individual point dataLabels that need\r\n // to be considered in drawDataLabels. These can only occur in object configs.\r\n if (options.dataLabels) {\r\n series._hasPointLabels = true;\r\n }\r\n\r\n // Same approach as above for markers\r\n if (options.marker) {\r\n series._hasPointMarkers = true;\r\n }\r\n }\r\n return ret;\r\n },\r\n\r\n /**\r\n * Destroy a point to clear memory. Its reference still stays in series.data.\r\n */\r\n destroy: function() {\r\n var point = this,\r\n series = point.series,\r\n chart = series.chart,\r\n hoverPoints = chart.hoverPoints,\r\n prop;\r\n\r\n chart.pointCount--;\r\n\r\n if (hoverPoints) {\r\n point.setState();\r\n erase(hoverPoints, point);\r\n if (!hoverPoints.length) {\r\n chart.hoverPoints = null;\r\n }\r\n }\r\n if (point === chart.hoverPoint) {\r\n point.onMouseOut();\r\n }\r\n\r\n // remove all events\r\n if (point.graphic || point.dataLabel) {\r\n // removeEvent and destroyElements are performance expensive\r\n removeEvent(point);\r\n point.destroyElements();\r\n }\r\n\r\n if (point.legendItem) {\r\n // pies have legend items\r\n chart.legend.destroyItem(point);\r\n }\r\n\r\n for (prop in point) {\r\n point[prop] = null;\r\n }\r\n },\r\n\r\n /**\r\n * Destroy SVG elements associated with the point\r\n */\r\n destroyElements: function() {\r\n var point = this,\r\n props = [\r\n \"graphic\",\r\n \"dataLabel\",\r\n \"dataLabelUpper\",\r\n \"group\",\r\n \"connector\",\r\n \"shadowGroup\"\r\n ],\r\n prop,\r\n i = 6;\r\n while (i--) {\r\n prop = props[i];\r\n if (point[prop]) {\r\n point[prop] = point[prop].destroy();\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Return the configuration hash needed for the data label and tooltip formatters\r\n */\r\n getLabelConfig: function() {\r\n var point = this;\r\n return {\r\n x: point.category,\r\n y: point.y,\r\n key: point.name || point.category,\r\n series: point.series,\r\n point: point,\r\n percentage: point.percentage,\r\n total: point.total || point.stackTotal\r\n };\r\n },\r\n\r\n /**\r\n * Toggle the selection status of a point\r\n * @param {Boolean} selected Whether to select or unselect the point.\r\n * @param {Boolean} accumulate Whether to add to the previous selection. By default,\r\n * this happens if the control key (Cmd on Mac) was pressed during clicking.\r\n */\r\n select: function(selected, accumulate) {\r\n var point = this,\r\n series = point.series,\r\n chart = series.chart;\r\n\r\n selected = pick(selected, !point.selected);\r\n\r\n // fire the event with the defalut handler\r\n point.firePointEvent(\r\n selected ? \"select\" : \"unselect\",\r\n { accumulate: accumulate },\r\n function() {\r\n point.selected = point.options.selected = selected;\r\n series.options.data[inArray(point, series.data)] = point.options;\r\n\r\n point.setState(selected && SELECT_STATE);\r\n\r\n // unselect all other points unless Ctrl or Cmd + click\r\n if (!accumulate) {\r\n each(chart.getSelectedPoints(), function(loopPoint) {\r\n if (loopPoint.selected && loopPoint !== point) {\r\n loopPoint.selected = loopPoint.options.selected = false;\r\n series.options.data[inArray(loopPoint, series.data)] =\r\n loopPoint.options;\r\n loopPoint.setState(NORMAL_STATE);\r\n loopPoint.firePointEvent(\"unselect\");\r\n }\r\n });\r\n }\r\n }\r\n );\r\n },\r\n\r\n /**\r\n * Runs on mouse over the point\r\n */\r\n onMouseOver: function(e) {\r\n var point = this,\r\n series = point.series,\r\n chart = series.chart,\r\n tooltip = chart.tooltip,\r\n hoverPoint = chart.hoverPoint;\r\n\r\n // set normal state to previous series\r\n if (hoverPoint && hoverPoint !== point) {\r\n hoverPoint.onMouseOut();\r\n }\r\n\r\n // trigger the event\r\n point.firePointEvent(\"mouseOver\");\r\n\r\n // update the tooltip\r\n if (tooltip && (!tooltip.shared || series.noSharedTooltip)) {\r\n tooltip.refresh(point, e);\r\n }\r\n\r\n // hover this\r\n point.setState(HOVER_STATE);\r\n chart.hoverPoint = point;\r\n },\r\n\r\n /**\r\n * Runs on mouse out from the point\r\n */\r\n onMouseOut: function() {\r\n var chart = this.series.chart,\r\n hoverPoints = chart.hoverPoints;\r\n\r\n if (!hoverPoints || inArray(this, hoverPoints) === -1) {\r\n // #887\r\n this.firePointEvent(\"mouseOut\");\r\n\r\n this.setState();\r\n chart.hoverPoint = null;\r\n }\r\n },\r\n\r\n /**\r\n * Extendable method for formatting each point's tooltip line\r\n *\r\n * @return {String} A string to be concatenated in to the common tooltip text\r\n */\r\n tooltipFormatter: function(pointFormat) {\r\n // Insert options for valueDecimals, valuePrefix, and valueSuffix\r\n var series = this.series,\r\n seriesTooltipOptions = series.tooltipOptions,\r\n valueDecimals = pick(seriesTooltipOptions.valueDecimals, \"\"),\r\n valuePrefix = seriesTooltipOptions.valuePrefix || \"\",\r\n valueSuffix = seriesTooltipOptions.valueSuffix || \"\";\r\n\r\n // Loop over the point array map and replace unformatted values with sprintf formatting markup\r\n each(series.pointArrayMap || [\"y\"], function(key) {\r\n key = \"{point.\" + key; // without the closing bracket\r\n if (valuePrefix || valueSuffix) {\r\n pointFormat = pointFormat.replace(\r\n key + \"}\",\r\n valuePrefix + key + \"}\" + valueSuffix\r\n );\r\n }\r\n pointFormat = pointFormat.replace(\r\n key + \"}\",\r\n key + \":,.\" + valueDecimals + \"f}\"\r\n );\r\n });\r\n\r\n return format(pointFormat, {\r\n point: this,\r\n series: this.series\r\n });\r\n },\r\n\r\n /**\r\n * Update the point with new options (typically x/y data) and optionally redraw the series.\r\n *\r\n * @param {Object} options Point options as defined in the series.data array\r\n * @param {Boolean} redraw Whether to redraw the chart or wait for an explicit call\r\n * @param {Boolean|Object} animation Whether to apply animation, and optionally animation\r\n * configuration\r\n *\r\n */\r\n update: function(options, redraw, animation) {\r\n var point = this,\r\n series = point.series,\r\n graphic = point.graphic,\r\n i,\r\n data = series.data,\r\n chart = series.chart,\r\n seriesOptions = series.options;\r\n\r\n redraw = pick(redraw, true);\r\n\r\n // fire the event with a default handler of doing the update\r\n point.firePointEvent(\"update\", { options: options }, function() {\r\n point.applyOptions(options);\r\n\r\n // update visuals\r\n if (isObject(options)) {\r\n series.getAttribs();\r\n if (graphic) {\r\n if (options && options.marker && options.marker.symbol) {\r\n point.graphic = graphic.destroy();\r\n }\r\n else {\r\n graphic.attr(point.pointAttr[point.state || \"\"]);\r\n }\r\n }\r\n }\r\n\r\n // record changes in the parallel arrays\r\n i = inArray(point, data);\r\n series.xData[i] = point.x;\r\n series.yData[i] = series.toYData ? series.toYData(point) : point.y;\r\n series.zData[i] = point.z;\r\n seriesOptions.data[i] = point.options;\r\n\r\n // redraw\r\n series.isDirty = series.isDirtyData = true;\r\n if (!series.fixedBox && series.hasCartesianSeries) {\r\n // #1906, #2320\r\n chart.isDirtyBox = true;\r\n }\r\n\r\n if (seriesOptions.legendType === \"point\") {\r\n // #1831, #1885\r\n chart.legend.destroyItem(point);\r\n }\r\n if (redraw) {\r\n chart.redraw(animation);\r\n }\r\n });\r\n },\r\n\r\n /**\r\n * Remove a point and optionally redraw the series and if necessary the axes\r\n * @param {Boolean} redraw Whether to redraw the chart or wait for an explicit call\r\n * @param {Boolean|Object} animation Whether to apply animation, and optionally animation\r\n * configuration\r\n */\r\n remove: function(redraw, animation) {\r\n var point = this,\r\n series = point.series,\r\n points = series.points,\r\n chart = series.chart,\r\n i,\r\n data = series.data;\r\n\r\n setAnimation(animation, chart);\r\n redraw = pick(redraw, true);\r\n\r\n // fire the event with a default handler of removing the point\r\n point.firePointEvent(\"remove\", null, function() {\r\n // splice all the parallel arrays\r\n i = inArray(point, data);\r\n if (data.length === points.length) {\r\n points.splice(i, 1);\r\n }\r\n data.splice(i, 1);\r\n series.options.data.splice(i, 1);\r\n series.xData.splice(i, 1);\r\n series.yData.splice(i, 1);\r\n series.zData.splice(i, 1);\r\n\r\n point.destroy();\r\n\r\n // redraw\r\n series.isDirty = true;\r\n series.isDirtyData = true;\r\n if (redraw) {\r\n chart.redraw();\r\n }\r\n });\r\n },\r\n\r\n /**\r\n * Fire an event on the Point object. Must not be renamed to fireEvent, as this\r\n * causes a name clash in MooTools\r\n * @param {String} eventType\r\n * @param {Object} eventArgs Additional event arguments\r\n * @param {Function} defaultFunction Default event handler\r\n */\r\n firePointEvent: function(eventType, eventArgs, defaultFunction) {\r\n var point = this,\r\n series = this.series,\r\n seriesOptions = series.options;\r\n\r\n // load event handlers on demand to save time on mouseover/out\r\n if (\r\n seriesOptions.point.events[eventType] ||\r\n (point.options &&\r\n point.options.events &&\r\n point.options.events[eventType])\r\n ) {\r\n this.importEvents();\r\n }\r\n\r\n // add default handler if in selection mode\r\n if (eventType === \"click\" && seriesOptions.allowPointSelect) {\r\n defaultFunction = function(event) {\r\n // Control key is for Windows, meta (= Cmd key) for Mac, Shift for Opera\r\n point.select(null, event.ctrlKey || event.metaKey || event.shiftKey);\r\n };\r\n }\r\n\r\n fireEvent(this, eventType, eventArgs, defaultFunction);\r\n },\r\n /**\r\n * Import events from the series' and point's options. Only do it on\r\n * demand, to save processing time on hovering.\r\n */\r\n importEvents: function() {\r\n if (!this.hasImportedEvents) {\r\n var point = this,\r\n options = merge(point.series.options.point, point.options),\r\n events = options.events,\r\n eventType;\r\n\r\n point.events = events;\r\n\r\n for (eventType in events) {\r\n addEvent(point, eventType, events[eventType]);\r\n }\r\n this.hasImportedEvents = true;\r\n }\r\n },\r\n\r\n /**\r\n * Set the point's state\r\n * @param {String} state\r\n */\r\n setState: function(state) {\r\n var point = this,\r\n plotX = point.plotX,\r\n plotY = point.plotY,\r\n series = point.series,\r\n stateOptions = series.options.states,\r\n markerOptions =\r\n defaultPlotOptions[series.type].marker && series.options.marker,\r\n normalDisabled = markerOptions && !markerOptions.enabled,\r\n markerStateOptions = markerOptions && markerOptions.states[state],\r\n stateDisabled =\r\n markerStateOptions && markerStateOptions.enabled === false,\r\n stateMarkerGraphic = series.stateMarkerGraphic,\r\n pointMarker = point.marker || {},\r\n chart = series.chart,\r\n radius,\r\n newSymbol,\r\n pointAttr = point.pointAttr;\r\n\r\n state = state || NORMAL_STATE; // empty string\r\n\r\n if (\r\n // already has this state\r\n state === point.state ||\r\n // selected points don't respond to hover\r\n (point.selected && state !== SELECT_STATE) ||\r\n // series' state options is disabled\r\n (stateOptions[state] && stateOptions[state].enabled === false) ||\r\n // general point marker's state options is disabled\r\n (state &&\r\n (stateDisabled || (normalDisabled && !markerStateOptions.enabled))) ||\r\n // individual point marker's state options is disabled\r\n (state &&\r\n pointMarker.states &&\r\n pointMarker.states[state] &&\r\n pointMarker.states[state].enabled === false) // #1610\r\n ) {\r\n return;\r\n }\r\n\r\n // apply hover styles to the existing point\r\n if (point.graphic) {\r\n radius =\r\n markerOptions && point.graphic.symbolName && pointAttr[state].r;\r\n point.graphic.attr(\r\n merge(\r\n pointAttr[state],\r\n radius\r\n ? {\r\n // new symbol attributes (#507, #612)\r\n x: plotX - radius,\r\n y: plotY - radius,\r\n width: 2 * radius,\r\n height: 2 * radius\r\n }\r\n : {}\r\n )\r\n );\r\n }\r\n else {\r\n // if a graphic is not applied to each point in the normal state, create a shared\r\n // graphic for the hover state\r\n if (state && markerStateOptions) {\r\n radius = markerStateOptions.radius;\r\n newSymbol = pointMarker.symbol || series.symbol;\r\n\r\n // If the point has another symbol than the previous one, throw away the\r\n // state marker graphic and force a new one (#1459)\r\n if (\r\n stateMarkerGraphic &&\r\n stateMarkerGraphic.currentSymbol !== newSymbol\r\n ) {\r\n stateMarkerGraphic = stateMarkerGraphic.destroy();\r\n }\r\n\r\n // Add a new state marker graphic\r\n if (!stateMarkerGraphic) {\r\n series.stateMarkerGraphic = stateMarkerGraphic = chart.renderer\r\n .symbol(\r\n newSymbol,\r\n plotX - radius,\r\n plotY - radius,\r\n 2 * radius,\r\n 2 * radius\r\n )\r\n .attr(pointAttr[state])\r\n .add(series.markerGroup);\r\n stateMarkerGraphic.currentSymbol = newSymbol;\r\n\r\n // Move the existing graphic\r\n }\r\n else {\r\n stateMarkerGraphic.attr({\r\n // #1054\r\n x: plotX - radius,\r\n y: plotY - radius\r\n });\r\n }\r\n }\r\n\r\n if (stateMarkerGraphic) {\r\n stateMarkerGraphic[\r\n state && chart.isInsidePlot(plotX, plotY) ? \"show\" : \"hide\"\r\n ]();\r\n }\r\n }\r\n\r\n point.state = state;\r\n }\r\n };\r\n\r\n /**\r\n * @classDescription The base function which all other series types inherit from. The data in the series is stored\r\n * in various arrays.\r\n *\r\n * - First, series.options.data contains all the original config options for\r\n * each point whether added by options or methods like series.addPoint.\r\n * - Next, series.data contains those values converted to points, but in case the series data length\r\n * exceeds the cropThreshold, or if the data is grouped, series.data doesn't contain all the points. It\r\n * only contains the points that have been created on demand.\r\n * - Then there's series.points that contains all currently visible point objects. In case of cropping,\r\n * the cropped-away points are not part of this array. The series.points array starts at series.cropStart\r\n * compared to series.data and series.options.data. If however the series data is grouped, these can't\r\n * be correlated one to one.\r\n * - series.xData and series.processedXData contain clean x values, equivalent to series.data and series.points.\r\n * - series.yData and series.processedYData contain clean x values, equivalent to series.data and series.points.\r\n *\r\n * @param {Object} chart\r\n * @param {Object} options\r\n */\r\n var Series = function() {};\r\n\r\n Series.prototype = {\r\n isCartesian: true,\r\n type: \"line\",\r\n pointClass: Point,\r\n sorted: true, // requires the data to be sorted\r\n requireSorting: true,\r\n pointAttrToOptions: {\r\n // mapping between SVG attributes and the corresponding options\r\n stroke: \"lineColor\",\r\n \"stroke-width\": \"lineWidth\",\r\n fill: \"fillColor\",\r\n r: \"radius\"\r\n },\r\n colorCounter: 0,\r\n init: function(chart, options) {\r\n var series = this,\r\n eventType,\r\n events,\r\n chartSeries = chart.series;\r\n\r\n series.chart = chart;\r\n series.options = options = series.setOptions(options); // merge with plotOptions\r\n series.linkedSeries = [];\r\n\r\n // bind the axes\r\n series.bindAxes();\r\n\r\n // set some variables\r\n extend(series, {\r\n name: options.name,\r\n state: NORMAL_STATE,\r\n pointAttr: {},\r\n visible: options.visible !== false, // true by default\r\n selected: options.selected === true // false by default\r\n });\r\n\r\n // special\r\n if (useCanVG) {\r\n options.animation = false;\r\n }\r\n\r\n // register event listeners\r\n events = options.events;\r\n for (eventType in events) {\r\n addEvent(series, eventType, events[eventType]);\r\n }\r\n if (\r\n (events && events.click) ||\r\n (options.point && options.point.events && options.point.events.click) ||\r\n options.allowPointSelect\r\n ) {\r\n chart.runTrackerClick = true;\r\n }\r\n\r\n series.getColor();\r\n series.getSymbol();\r\n\r\n // set the data\r\n series.setData(options.data, false);\r\n\r\n // Mark cartesian\r\n if (series.isCartesian) {\r\n chart.hasCartesianSeries = true;\r\n }\r\n\r\n // Register it in the chart\r\n chartSeries.push(series);\r\n series._i = chartSeries.length - 1;\r\n\r\n // Sort series according to index option (#248, #1123)\r\n stableSort(chartSeries, function(a, b) {\r\n return pick(a.options.index, a._i) - pick(b.options.index, a._i);\r\n });\r\n each(chartSeries, function(series, i) {\r\n series.index = i;\r\n series.name = series.name || \"Series \" + (i + 1);\r\n });\r\n },\r\n\r\n /**\r\n * Set the xAxis and yAxis properties of cartesian series, and register the series\r\n * in the axis.series array\r\n */\r\n bindAxes: function() {\r\n var series = this,\r\n seriesOptions = series.options,\r\n chart = series.chart,\r\n axisOptions;\r\n\r\n if (series.isCartesian) {\r\n each([\"xAxis\", \"yAxis\"], function(AXIS) {\r\n // repeat for xAxis and yAxis\r\n\r\n each(chart[AXIS], function(axis) {\r\n // loop through the chart's axis objects\r\n\r\n axisOptions = axis.options;\r\n\r\n // apply if the series xAxis or yAxis option mathches the number of the\r\n // axis, or if undefined, use the first axis\r\n if (\r\n seriesOptions[AXIS] === axisOptions.index ||\r\n (seriesOptions[AXIS] !== UNDEFINED &&\r\n seriesOptions[AXIS] === axisOptions.id) ||\r\n (seriesOptions[AXIS] === UNDEFINED && axisOptions.index === 0)\r\n ) {\r\n // register this series in the axis.series lookup\r\n axis.series.push(series);\r\n\r\n // set this series.xAxis or series.yAxis reference\r\n series[AXIS] = axis;\r\n\r\n // mark dirty for redraw\r\n axis.isDirty = true;\r\n }\r\n });\r\n\r\n // The series needs an X and an Y axis\r\n if (!series[AXIS]) {\r\n error(18, true);\r\n }\r\n });\r\n }\r\n },\r\n\r\n /**\r\n * Return an auto incremented x value based on the pointStart and pointInterval options.\r\n * This is only used if an x value is not given for the point that calls autoIncrement.\r\n */\r\n autoIncrement: function() {\r\n var series = this,\r\n options = series.options,\r\n xIncrement = series.xIncrement;\r\n\r\n xIncrement = pick(xIncrement, options.pointStart, 0);\r\n\r\n series.pointInterval = pick(\r\n series.pointInterval,\r\n options.pointInterval,\r\n 1\r\n );\r\n\r\n series.xIncrement = xIncrement + series.pointInterval;\r\n return xIncrement;\r\n },\r\n\r\n /**\r\n * Divide the series data into segments divided by null values.\r\n */\r\n getSegments: function() {\r\n var series = this,\r\n lastNull = -1,\r\n segments = [],\r\n i,\r\n points = series.points,\r\n pointsLength = points.length;\r\n\r\n if (pointsLength) {\r\n // no action required for []\r\n\r\n // if connect nulls, just remove null points\r\n if (series.options.connectNulls) {\r\n i = pointsLength;\r\n while (i--) {\r\n if (points[i].y === null) {\r\n points.splice(i, 1);\r\n }\r\n }\r\n if (points.length) {\r\n segments = [points];\r\n }\r\n\r\n // else, split on null points\r\n }\r\n else {\r\n each(points, function(point, i) {\r\n if (point.y === null) {\r\n if (i > lastNull + 1) {\r\n segments.push(points.slice(lastNull + 1, i));\r\n }\r\n lastNull = i;\r\n }\r\n else if (i === pointsLength - 1) {\r\n // last value\r\n segments.push(points.slice(lastNull + 1, i + 1));\r\n }\r\n });\r\n }\r\n }\r\n\r\n // register it\r\n series.segments = segments;\r\n },\r\n\r\n /**\r\n * Set the series options by merging from the options tree\r\n * @param {Object} itemOptions\r\n */\r\n setOptions: function(itemOptions) {\r\n var chart = this.chart,\r\n chartOptions = chart.options,\r\n plotOptions = chartOptions.plotOptions,\r\n typeOptions = plotOptions[this.type],\r\n options;\r\n\r\n this.userOptions = itemOptions;\r\n\r\n options = merge(typeOptions, plotOptions.series, itemOptions);\r\n\r\n // the tooltip options are merged between global and series specific options\r\n this.tooltipOptions = merge(chartOptions.tooltip, options.tooltip);\r\n\r\n // Delte marker object if not allowed (#1125)\r\n if (typeOptions.marker === null) {\r\n delete options.marker;\r\n }\r\n\r\n return options;\r\n },\r\n /**\r\n * Get the series' color\r\n */\r\n getColor: function() {\r\n var options = this.options,\r\n userOptions = this.userOptions,\r\n defaultColors = this.chart.options.colors,\r\n counters = this.chart.counters,\r\n color,\r\n colorIndex;\r\n\r\n color = options.color || defaultPlotOptions[this.type].color;\r\n\r\n if (!color && !options.colorByPoint) {\r\n if (defined(userOptions._colorIndex)) {\r\n // after Series.update()\r\n colorIndex = userOptions._colorIndex;\r\n }\r\n else {\r\n userOptions._colorIndex = counters.color;\r\n colorIndex = counters.color++;\r\n }\r\n color = defaultColors[colorIndex];\r\n }\r\n\r\n this.color = color;\r\n counters.wrapColor(defaultColors.length);\r\n },\r\n /**\r\n * Get the series' symbol\r\n */\r\n getSymbol: function() {\r\n var series = this,\r\n userOptions = series.userOptions,\r\n seriesMarkerOption = series.options.marker,\r\n chart = series.chart,\r\n defaultSymbols = chart.options.symbols,\r\n counters = chart.counters,\r\n symbolIndex;\r\n\r\n series.symbol = seriesMarkerOption.symbol;\r\n if (!series.symbol) {\r\n if (defined(userOptions._symbolIndex)) {\r\n // after Series.update()\r\n symbolIndex = userOptions._symbolIndex;\r\n }\r\n else {\r\n userOptions._symbolIndex = counters.symbol;\r\n symbolIndex = counters.symbol++;\r\n }\r\n series.symbol = defaultSymbols[symbolIndex];\r\n }\r\n\r\n // don't substract radius in image symbols (#604)\r\n if (/^url/.test(series.symbol)) {\r\n seriesMarkerOption.radius = 0;\r\n }\r\n counters.wrapSymbol(defaultSymbols.length);\r\n },\r\n\r\n /**\r\n * Get the series' symbol in the legend. This method should be overridable to create custom\r\n * symbols through Highcharts.seriesTypes[type].prototype.drawLegendSymbols.\r\n *\r\n * @param {Object} legend The legend object\r\n */\r\n drawLegendSymbol: function(legend) {\r\n var options = this.options,\r\n markerOptions = options.marker,\r\n radius,\r\n legendOptions = legend.options,\r\n legendSymbol,\r\n symbolWidth = legendOptions.symbolWidth,\r\n renderer = this.chart.renderer,\r\n legendItemGroup = this.legendGroup,\r\n verticalCenter =\r\n legend.baseline -\r\n mathRound(\r\n renderer.fontMetrics(legendOptions.itemStyle.fontSize).b * 0.3\r\n ),\r\n attr;\r\n\r\n // Draw the line\r\n if (options.lineWidth) {\r\n attr = {\r\n \"stroke-width\": options.lineWidth\r\n };\r\n if (options.dashStyle) {\r\n attr.dashstyle = options.dashStyle;\r\n }\r\n this.legendLine = renderer\r\n .path([M, 0, verticalCenter, L, symbolWidth, verticalCenter])\r\n .attr(attr)\r\n .add(legendItemGroup);\r\n }\r\n\r\n // Draw the marker\r\n if (markerOptions && markerOptions.enabled) {\r\n radius = markerOptions.radius;\r\n this.legendSymbol = legendSymbol = renderer\r\n .symbol(\r\n this.symbol,\r\n symbolWidth / 2 - radius,\r\n verticalCenter - radius,\r\n 2 * radius,\r\n 2 * radius\r\n )\r\n .add(legendItemGroup);\r\n legendSymbol.isMarker = true;\r\n }\r\n },\r\n\r\n /**\r\n * Add a point dynamically after chart load time\r\n * @param {Object} options Point options as given in series.data\r\n * @param {Boolean} redraw Whether to redraw the chart or wait for an explicit call\r\n * @param {Boolean} shift If shift is true, a point is shifted off the start\r\n * of the series as one is appended to the end.\r\n * @param {Boolean|Object} animation Whether to apply animation, and optionally animation\r\n * configuration\r\n */\r\n addPoint: function(options, redraw, shift, animation) {\r\n var series = this,\r\n seriesOptions = series.options,\r\n data = series.data,\r\n graph = series.graph,\r\n area = series.area,\r\n chart = series.chart,\r\n xData = series.xData,\r\n yData = series.yData,\r\n zData = series.zData,\r\n names = series.xAxis && series.xAxis.names,\r\n currentShift = (graph && graph.shift) || 0,\r\n dataOptions = seriesOptions.data,\r\n point,\r\n isInTheMiddle,\r\n x,\r\n i;\r\n\r\n setAnimation(animation, chart);\r\n\r\n // Make graph animate sideways\r\n if (shift) {\r\n each([graph, area, series.graphNeg, series.areaNeg], function(shape) {\r\n if (shape) {\r\n shape.shift = currentShift + 1;\r\n }\r\n });\r\n }\r\n if (area) {\r\n area.isArea = true; // needed in animation, both with and without shift\r\n }\r\n\r\n // Optional redraw, defaults to true\r\n redraw = pick(redraw, true);\r\n\r\n // Get options and push the point to xData, yData and series.options. In series.generatePoints\r\n // the Point instance will be created on demand and pushed to the series.data array.\r\n point = { series: series };\r\n series.pointClass.prototype.applyOptions.apply(point, [options]);\r\n x = point.x;\r\n\r\n // Get the insertion point\r\n i = xData.length;\r\n if (series.requireSorting && x < xData[i - 1]) {\r\n isInTheMiddle = true;\r\n while (i && xData[i - 1] > x) {\r\n i--;\r\n }\r\n }\r\n\r\n xData.splice(i, 0, x);\r\n yData.splice(i, 0, series.toYData ? series.toYData(point) : point.y);\r\n zData.splice(i, 0, point.z);\r\n if (names) {\r\n names[x] = point.name;\r\n }\r\n dataOptions.splice(i, 0, options);\r\n\r\n if (isInTheMiddle) {\r\n series.data.splice(i, 0, null);\r\n series.processData();\r\n }\r\n\r\n // Generate points to be added to the legend (#1329)\r\n if (seriesOptions.legendType === \"point\") {\r\n series.generatePoints();\r\n }\r\n\r\n // Shift the first point off the parallel arrays\r\n // todo: consider series.removePoint(i) method\r\n if (shift) {\r\n if (data[0] && data[0].remove) {\r\n data[0].remove(false);\r\n }\r\n else {\r\n data.shift();\r\n xData.shift();\r\n yData.shift();\r\n zData.shift();\r\n dataOptions.shift();\r\n }\r\n }\r\n\r\n // redraw\r\n series.isDirty = true;\r\n series.isDirtyData = true;\r\n if (redraw) {\r\n series.getAttribs(); // #1937\r\n chart.redraw();\r\n }\r\n },\r\n\r\n /**\r\n * Replace the series data with a new set of data\r\n * @param {Object} data\r\n * @param {Object} redraw\r\n */\r\n setData: function(data, redraw) {\r\n var series = this,\r\n oldData = series.points,\r\n options = series.options,\r\n chart = series.chart,\r\n firstPoint = null,\r\n xAxis = series.xAxis,\r\n names = xAxis && xAxis.names,\r\n i;\r\n\r\n // reset properties\r\n series.xIncrement = null;\r\n series.pointRange = xAxis && xAxis.categories ? 1 : options.pointRange;\r\n\r\n series.colorCounter = 0; // for series with colorByPoint (#1547)\r\n\r\n // parallel arrays\r\n var xData = [],\r\n yData = [],\r\n zData = [],\r\n dataLength = data ? data.length : [],\r\n turboThreshold = pick(options.turboThreshold, 1000),\r\n pt,\r\n pointArrayMap = series.pointArrayMap,\r\n valueCount = pointArrayMap && pointArrayMap.length,\r\n hasToYData = !!series.toYData;\r\n\r\n // In turbo mode, only one- or twodimensional arrays of numbers are allowed. The\r\n // first value is tested, and we assume that all the rest are defined the same\r\n // way. Although the 'for' loops are similar, they are repeated inside each\r\n // if-else conditional for max performance.\r\n if (turboThreshold && dataLength > turboThreshold) {\r\n // find the first non-null point\r\n i = 0;\r\n while (firstPoint === null && i < dataLength) {\r\n firstPoint = data[i];\r\n i++;\r\n }\r\n\r\n if (isNumber(firstPoint)) {\r\n // assume all points are numbers\r\n var x = pick(options.pointStart, 0),\r\n pointInterval = pick(options.pointInterval, 1);\r\n\r\n for (i = 0; i < dataLength; i++) {\r\n xData[i] = x;\r\n yData[i] = data[i];\r\n x += pointInterval;\r\n }\r\n series.xIncrement = x;\r\n }\r\n else if (isArray(firstPoint)) {\r\n // assume all points are arrays\r\n if (valueCount) {\r\n // [x, low, high] or [x, o, h, l, c]\r\n for (i = 0; i < dataLength; i++) {\r\n pt = data[i];\r\n xData[i] = pt[0];\r\n yData[i] = pt.slice(1, valueCount + 1);\r\n }\r\n }\r\n else {\r\n // [x, y]\r\n for (i = 0; i < dataLength; i++) {\r\n pt = data[i];\r\n xData[i] = pt[0];\r\n yData[i] = pt[1];\r\n }\r\n }\r\n }\r\n else {\r\n error(12); // Highcharts expects configs to be numbers or arrays in turbo mode\r\n }\r\n }\r\n else {\r\n for (i = 0; i < dataLength; i++) {\r\n if (data[i] !== UNDEFINED) {\r\n // stray commas in oldIE\r\n pt = { series: series };\r\n series.pointClass.prototype.applyOptions.apply(pt, [data[i]]);\r\n xData[i] = pt.x;\r\n yData[i] = hasToYData ? series.toYData(pt) : pt.y;\r\n zData[i] = pt.z;\r\n if (names && pt.name) {\r\n names[pt.x] = pt.name; // #2046\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Forgetting to cast strings to numbers is a common caveat when handling CSV or JSON\r\n if (isString(yData[0])) {\r\n error(14, true);\r\n }\r\n\r\n series.data = [];\r\n series.options.data = data;\r\n series.xData = xData;\r\n series.yData = yData;\r\n series.zData = zData;\r\n\r\n // destroy old points\r\n i = (oldData && oldData.length) || 0;\r\n while (i--) {\r\n if (oldData[i] && oldData[i].destroy) {\r\n oldData[i].destroy();\r\n }\r\n }\r\n\r\n // reset minRange (#878)\r\n if (xAxis) {\r\n xAxis.minRange = xAxis.userMinRange;\r\n }\r\n\r\n // redraw\r\n series.isDirty = series.isDirtyData = chart.isDirtyBox = true;\r\n if (pick(redraw, true)) {\r\n chart.redraw(false);\r\n }\r\n },\r\n\r\n /**\r\n * Remove a series and optionally redraw the chart\r\n *\r\n * @param {Boolean} redraw Whether to redraw the chart or wait for an explicit call\r\n * @param {Boolean|Object} animation Whether to apply animation, and optionally animation\r\n * configuration\r\n */\r\n\r\n remove: function(redraw, animation) {\r\n var series = this,\r\n chart = series.chart;\r\n redraw = pick(redraw, true);\r\n\r\n if (!series.isRemoving) {\r\n /* prevent triggering native event in jQuery\r\n\t\t\t\t(calling the remove function from the remove event) */\r\n series.isRemoving = true;\r\n\r\n // fire the event with a default handler of removing the point\r\n fireEvent(series, \"remove\", null, function() {\r\n // destroy elements\r\n series.destroy();\r\n\r\n // redraw\r\n chart.isDirtyLegend = chart.isDirtyBox = true;\r\n chart.linkSeries();\r\n\r\n if (redraw) {\r\n chart.redraw(animation);\r\n }\r\n });\r\n }\r\n series.isRemoving = false;\r\n },\r\n\r\n /**\r\n * Process the data by cropping away unused data points if the series is longer\r\n * than the crop threshold. This saves computing time for lage series.\r\n */\r\n processData: function(force) {\r\n var series = this,\r\n processedXData = series.xData, // copied during slice operation below\r\n processedYData = series.yData,\r\n dataLength = processedXData.length,\r\n croppedData,\r\n cropStart = 0,\r\n cropped,\r\n distance,\r\n closestPointRange,\r\n xAxis = series.xAxis,\r\n i, // loop variable\r\n options = series.options,\r\n cropThreshold = options.cropThreshold,\r\n isCartesian = series.isCartesian;\r\n\r\n // If the series data or axes haven't changed, don't go through this. Return false to pass\r\n // the message on to override methods like in data grouping.\r\n if (\r\n isCartesian &&\r\n !series.isDirty &&\r\n !xAxis.isDirty &&\r\n !series.yAxis.isDirty &&\r\n !force\r\n ) {\r\n return false;\r\n }\r\n\r\n // optionally filter out points outside the plot area\r\n if (\r\n isCartesian &&\r\n series.sorted &&\r\n (!cropThreshold || dataLength > cropThreshold || series.forceCrop)\r\n ) {\r\n var min = xAxis.min,\r\n max = xAxis.max;\r\n\r\n // it's outside current extremes\r\n if (processedXData[dataLength - 1] < min || processedXData[0] > max) {\r\n processedXData = [];\r\n processedYData = [];\r\n\r\n // only crop if it's actually spilling out\r\n }\r\n else if (\r\n processedXData[0] < min ||\r\n processedXData[dataLength - 1] > max\r\n ) {\r\n croppedData = this.cropData(series.xData, series.yData, min, max);\r\n processedXData = croppedData.xData;\r\n processedYData = croppedData.yData;\r\n cropStart = croppedData.start;\r\n cropped = true;\r\n }\r\n }\r\n\r\n // Find the closest distance between processed points\r\n for (i = processedXData.length - 1; i >= 0; i--) {\r\n distance = processedXData[i] - processedXData[i - 1];\r\n if (\r\n distance > 0 &&\r\n (closestPointRange === UNDEFINED || distance < closestPointRange)\r\n ) {\r\n closestPointRange = distance;\r\n\r\n // Unsorted data is not supported by the line tooltip, as well as data grouping and\r\n // navigation in Stock charts (#725) and width calculation of columns (#1900)\r\n }\r\n else if (distance < 0 && series.requireSorting) {\r\n error(15);\r\n }\r\n }\r\n\r\n // Record the properties\r\n series.cropped = cropped; // undefined or true\r\n series.cropStart = cropStart;\r\n series.processedXData = processedXData;\r\n series.processedYData = processedYData;\r\n\r\n if (options.pointRange === null) {\r\n // null means auto, as for columns, candlesticks and OHLC\r\n series.pointRange = closestPointRange || 1;\r\n }\r\n series.closestPointRange = closestPointRange;\r\n },\r\n\r\n /**\r\n * Iterate over xData and crop values between min and max. Returns object containing crop start/end\r\n * cropped xData with corresponding part of yData, dataMin and dataMax within the cropped range\r\n */\r\n cropData: function(xData, yData, min, max) {\r\n var dataLength = xData.length,\r\n cropStart = 0,\r\n cropEnd = dataLength,\r\n cropShoulder = pick(this.cropShoulder, 1), // line-type series need one point outside\r\n i;\r\n\r\n // iterate up to find slice start\r\n for (i = 0; i < dataLength; i++) {\r\n if (xData[i] >= min) {\r\n cropStart = mathMax(0, i - cropShoulder);\r\n break;\r\n }\r\n }\r\n\r\n // proceed to find slice end\r\n for (; i < dataLength; i++) {\r\n if (xData[i] > max) {\r\n cropEnd = i + cropShoulder;\r\n break;\r\n }\r\n }\r\n\r\n return {\r\n xData: xData.slice(cropStart, cropEnd),\r\n yData: yData.slice(cropStart, cropEnd),\r\n start: cropStart,\r\n end: cropEnd\r\n };\r\n },\r\n\r\n /**\r\n * Generate the data point after the data has been processed by cropping away\r\n * unused points and optionally grouped in Highcharts Stock.\r\n */\r\n generatePoints: function() {\r\n var series = this,\r\n options = series.options,\r\n dataOptions = options.data,\r\n data = series.data,\r\n dataLength,\r\n processedXData = series.processedXData,\r\n processedYData = series.processedYData,\r\n pointClass = series.pointClass,\r\n processedDataLength = processedXData.length,\r\n cropStart = series.cropStart || 0,\r\n cursor,\r\n hasGroupedData = series.hasGroupedData,\r\n point,\r\n points = [],\r\n i;\r\n\r\n if (!data && !hasGroupedData) {\r\n var arr = [];\r\n arr.length = dataOptions.length;\r\n data = series.data = arr;\r\n }\r\n\r\n for (i = 0; i < processedDataLength; i++) {\r\n cursor = cropStart + i;\r\n if (!hasGroupedData) {\r\n if (data[cursor]) {\r\n point = data[cursor];\r\n }\r\n else if (dataOptions[cursor] !== UNDEFINED) {\r\n // #970\r\n data[cursor] = point = new pointClass().init(\r\n series,\r\n dataOptions[cursor],\r\n processedXData[i]\r\n );\r\n }\r\n points[i] = point;\r\n }\r\n else {\r\n // splat the y data in case of ohlc data array\r\n points[i] = new pointClass().init(\r\n series,\r\n [processedXData[i]].concat(splat(processedYData[i]))\r\n );\r\n }\r\n }\r\n\r\n // Hide cropped-away points - this only runs when the number of points is above cropThreshold, or when\r\n // swithching view from non-grouped data to grouped data (#637)\r\n if (\r\n data &&\r\n (processedDataLength !== (dataLength = data.length) || hasGroupedData)\r\n ) {\r\n for (i = 0; i < dataLength; i++) {\r\n if (i === cropStart && !hasGroupedData) {\r\n // when has grouped data, clear all points\r\n i += processedDataLength;\r\n }\r\n if (data[i]) {\r\n data[i].destroyElements();\r\n data[i].plotX = UNDEFINED; // #1003\r\n }\r\n }\r\n }\r\n\r\n series.data = data;\r\n series.points = points;\r\n },\r\n\r\n /**\r\n * Adds series' points value to corresponding stack\r\n */\r\n setStackedPoints: function() {\r\n if (\r\n !this.options.stacking ||\r\n (this.visible !== true &&\r\n this.chart.options.chart.ignoreHiddenSeries !== false)\r\n ) {\r\n return;\r\n }\r\n\r\n var series = this,\r\n xData = series.processedXData,\r\n yData = series.processedYData,\r\n stackedYData = [],\r\n yDataLength = yData.length,\r\n seriesOptions = series.options,\r\n threshold = seriesOptions.threshold,\r\n stackOption = seriesOptions.stack,\r\n stacking = seriesOptions.stacking,\r\n stackKey = series.stackKey,\r\n negKey = \"-\" + stackKey,\r\n negStacks = series.negStacks,\r\n yAxis = series.yAxis,\r\n stacks = yAxis.stacks,\r\n oldStacks = yAxis.oldStacks,\r\n isNegative,\r\n stack,\r\n other,\r\n key,\r\n i,\r\n x,\r\n y;\r\n\r\n // loop over the non-null y values and read them into a local array\r\n for (i = 0; i < yDataLength; i++) {\r\n x = xData[i];\r\n y = yData[i];\r\n\r\n // Read stacked values into a stack based on the x value,\r\n // the sign of y and the stack key. Stacking is also handled for null values (#739)\r\n isNegative = negStacks && y < threshold;\r\n key = isNegative ? negKey : stackKey;\r\n\r\n // Create empty object for this stack if it doesn't exist yet\r\n if (!stacks[key]) {\r\n stacks[key] = {};\r\n }\r\n\r\n // Initialize StackItem for this x\r\n if (!stacks[key][x]) {\r\n if (oldStacks[key] && oldStacks[key][x]) {\r\n stacks[key][x] = oldStacks[key][x];\r\n stacks[key][x].total = null;\r\n }\r\n else {\r\n stacks[key][x] = new StackItem(\r\n yAxis,\r\n yAxis.options.stackLabels,\r\n isNegative,\r\n x,\r\n stackOption,\r\n stacking\r\n );\r\n }\r\n }\r\n\r\n // If the StackItem doesn't exist, create it first\r\n stack = stacks[key][x];\r\n stack.points[series.index] = [stack.cum || 0];\r\n\r\n // Add value to the stack total\r\n if (stacking === \"percent\") {\r\n // Percent stacked column, totals are the same for the positive and negative stacks\r\n other = isNegative ? stackKey : negKey;\r\n if (negStacks && stacks[other] && stacks[other][x]) {\r\n other = stacks[other][x];\r\n stack.total = other.total =\r\n mathMax(other.total, stack.total) + mathAbs(y) || 0;\r\n\r\n // Percent stacked areas\r\n }\r\n else {\r\n stack.total += mathAbs(y) || 0;\r\n }\r\n }\r\n else {\r\n stack.total += y || 0;\r\n }\r\n\r\n stack.cum = (stack.cum || 0) + (y || 0);\r\n\r\n stack.points[series.index].push(stack.cum);\r\n stackedYData[i] = stack.cum;\r\n }\r\n\r\n if (stacking === \"percent\") {\r\n yAxis.usePercentage = true;\r\n }\r\n\r\n this.stackedYData = stackedYData; // To be used in getExtremes\r\n\r\n // Reset old stacks\r\n yAxis.oldStacks = {};\r\n },\r\n\r\n /**\r\n * Iterate over all stacks and compute the absolute values to percent\r\n */\r\n setPercentStacks: function() {\r\n var series = this,\r\n stackKey = series.stackKey,\r\n stacks = series.yAxis.stacks;\r\n\r\n each([stackKey, \"-\" + stackKey], function(key) {\r\n var i = series.xData.length,\r\n x,\r\n stack,\r\n pointExtremes,\r\n totalFactor;\r\n\r\n while (i--) {\r\n x = series.xData[i];\r\n stack = stacks[key] && stacks[key][x];\r\n pointExtremes = stack && stack.points[series.index];\r\n if (pointExtremes) {\r\n totalFactor = stack.total ? 100 / stack.total : 0;\r\n pointExtremes[0] = correctFloat(pointExtremes[0] * totalFactor); // Y bottom value\r\n pointExtremes[1] = correctFloat(pointExtremes[1] * totalFactor); // Y value\r\n series.stackedYData[i] = pointExtremes[1];\r\n }\r\n }\r\n });\r\n },\r\n\r\n /**\r\n * Calculate Y extremes for visible data\r\n */\r\n getExtremes: function() {\r\n var xAxis = this.xAxis,\r\n yAxis = this.yAxis,\r\n xData = this.processedXData,\r\n yData = this.stackedYData || this.processedYData,\r\n yDataLength = yData.length,\r\n activeYData = [],\r\n activeCounter = 0,\r\n xExtremes = xAxis.getExtremes(), // #2117, need to compensate for log X axis\r\n xMin = xExtremes.min,\r\n xMax = xExtremes.max,\r\n validValue,\r\n withinRange,\r\n dataMin,\r\n dataMax,\r\n x,\r\n y,\r\n i,\r\n j;\r\n\r\n for (i = 0; i < yDataLength; i++) {\r\n x = xData[i];\r\n y = yData[i];\r\n\r\n // For points within the visible range, including the first point outside the\r\n // visible range, consider y extremes\r\n validValue =\r\n y !== null &&\r\n y !== UNDEFINED &&\r\n (!yAxis.isLog || (y.length || y > 0));\r\n withinRange =\r\n this.getExtremesFromAll ||\r\n this.cropped ||\r\n ((xData[i + 1] || x) >= xMin && (xData[i - 1] || x) <= xMax);\r\n\r\n if (validValue && withinRange) {\r\n j = y.length;\r\n if (j) {\r\n // array, like ohlc or range data\r\n while (j--) {\r\n if (y[j] !== null) {\r\n activeYData[activeCounter++] = y[j];\r\n }\r\n }\r\n }\r\n else {\r\n activeYData[activeCounter++] = y;\r\n }\r\n }\r\n }\r\n this.dataMin = pick(dataMin, arrayMin(activeYData));\r\n this.dataMax = pick(dataMax, arrayMax(activeYData));\r\n },\r\n\r\n /**\r\n * Translate data points from raw data values to chart specific positioning data\r\n * needed later in drawPoints, drawGraph and drawTracker.\r\n */\r\n translate: function() {\r\n if (!this.processedXData) {\r\n // hidden series\r\n this.processData();\r\n }\r\n this.generatePoints();\r\n var series = this,\r\n options = series.options,\r\n stacking = options.stacking,\r\n xAxis = series.xAxis,\r\n categories = xAxis.categories,\r\n yAxis = series.yAxis,\r\n points = series.points,\r\n dataLength = points.length,\r\n hasModifyValue = !!series.modifyValue,\r\n i,\r\n pointPlacement = options.pointPlacement,\r\n dynamicallyPlaced =\r\n pointPlacement === \"between\" || isNumber(pointPlacement),\r\n threshold = options.threshold;\r\n\r\n // Translate each point\r\n for (i = 0; i < dataLength; i++) {\r\n var point = points[i],\r\n xValue = point.x,\r\n yValue = point.y,\r\n yBottom = point.low,\r\n stack =\r\n yAxis.stacks[\r\n (series.negStacks && yValue < threshold ? \"-\" : \"\") +\r\n series.stackKey\r\n ],\r\n pointStack,\r\n stackValues;\r\n\r\n // Discard disallowed y values for log axes\r\n if (yAxis.isLog && yValue <= 0) {\r\n point.y = yValue = null;\r\n }\r\n\r\n // Get the plotX translation\r\n point.plotX = xAxis.translate(\r\n xValue,\r\n 0,\r\n 0,\r\n 0,\r\n 1,\r\n pointPlacement,\r\n this.type === \"flags\"\r\n ); // Math.round fixes #591\r\n\r\n // Calculate the bottom y value for stacked series\r\n if (stacking && series.visible && stack && stack[xValue]) {\r\n pointStack = stack[xValue];\r\n stackValues = pointStack.points[series.index];\r\n yBottom = stackValues[0];\r\n yValue = stackValues[1];\r\n\r\n if (yBottom === 0) {\r\n yBottom = pick(threshold, yAxis.min);\r\n }\r\n if (yAxis.isLog && yBottom <= 0) {\r\n // #1200, #1232\r\n yBottom = null;\r\n }\r\n\r\n point.total = point.stackTotal = pointStack.total;\r\n point.percentage =\r\n stacking === \"percent\" && (point.y / pointStack.total) * 100;\r\n point.stackY = yValue;\r\n\r\n // Place the stack label\r\n pointStack.setOffset(series.pointXOffset || 0, series.barW || 0);\r\n }\r\n\r\n // Set translated yBottom or remove it\r\n point.yBottom = defined(yBottom)\r\n ? yAxis.translate(yBottom, 0, 1, 0, 1)\r\n : null;\r\n\r\n // general hook, used for Highstock compare mode\r\n if (hasModifyValue) {\r\n yValue = series.modifyValue(yValue, point);\r\n }\r\n\r\n // Set the the plotY value, reset it for redraws\r\n point.plotY =\r\n typeof yValue === \"number\" && yValue !== Infinity\r\n ? //mathRound(yAxis.translate(yValue, 0, 1, 0, 1) * 10) / 10 : // Math.round fixes #591\r\n yAxis.translate(yValue, 0, 1, 0, 1)\r\n : UNDEFINED;\r\n\r\n // Set client related positions for mouse tracking\r\n point.clientX = dynamicallyPlaced\r\n ? xAxis.translate(xValue, 0, 0, 0, 1)\r\n : point.plotX; // #1514\r\n\r\n point.negative = point.y < (threshold || 0);\r\n\r\n // some API data\r\n point.category =\r\n categories && categories[point.x] !== UNDEFINED\r\n ? categories[point.x]\r\n : point.x;\r\n }\r\n\r\n // now that we have the cropped data, build the segments\r\n series.getSegments();\r\n },\r\n /**\r\n * Memoize tooltip texts and positions\r\n */\r\n setTooltipPoints: function(renew) {\r\n var series = this,\r\n points = [],\r\n pointsLength,\r\n low,\r\n high,\r\n xAxis = series.xAxis,\r\n xExtremes = xAxis && xAxis.getExtremes(),\r\n axisLength = xAxis\r\n ? xAxis.tooltipLen || xAxis.len\r\n : series.chart.plotSizeX, // tooltipLen and tooltipPosName used in polar\r\n point,\r\n pointX,\r\n nextPoint,\r\n i,\r\n tooltipPoints = []; // a lookup array for each pixel in the x dimension\r\n\r\n // don't waste resources if tracker is disabled\r\n if (series.options.enableMouseTracking === false) {\r\n return;\r\n }\r\n\r\n // renew\r\n if (renew) {\r\n series.tooltipPoints = null;\r\n }\r\n\r\n // concat segments to overcome null values\r\n each(series.segments || series.points, function(segment) {\r\n points = points.concat(segment);\r\n });\r\n\r\n // Reverse the points in case the X axis is reversed\r\n if (xAxis && xAxis.reversed) {\r\n points = points.reverse();\r\n }\r\n\r\n // Polar needs additional shaping\r\n if (series.orderTooltipPoints) {\r\n series.orderTooltipPoints(points);\r\n }\r\n\r\n // Assign each pixel position to the nearest point\r\n pointsLength = points.length;\r\n for (i = 0; i < pointsLength; i++) {\r\n point = points[i];\r\n pointX = point.x;\r\n if (pointX >= xExtremes.min && pointX <= xExtremes.max) {\r\n // #1149\r\n nextPoint = points[i + 1];\r\n\r\n // Set this range's low to the last range's high plus one\r\n low = high === UNDEFINED ? 0 : high + 1;\r\n // Now find the new high\r\n high = points[i + 1]\r\n ? mathMin(\r\n mathMax(\r\n 0,\r\n mathFloor(\r\n // #2070\r\n (point.clientX +\r\n (nextPoint\r\n ? nextPoint.wrappedClientX || nextPoint.clientX\r\n : axisLength)) /\r\n 2\r\n )\r\n ),\r\n axisLength\r\n )\r\n : axisLength;\r\n\r\n while (low >= 0 && low <= high) {\r\n tooltipPoints[low++] = point;\r\n }\r\n }\r\n }\r\n series.tooltipPoints = tooltipPoints;\r\n },\r\n\r\n /**\r\n * Format the header of the tooltip\r\n */\r\n tooltipHeaderFormatter: function(point) {\r\n var series = this,\r\n tooltipOptions = series.tooltipOptions,\r\n xDateFormat = tooltipOptions.xDateFormat,\r\n dateTimeLabelFormats = tooltipOptions.dateTimeLabelFormats,\r\n xAxis = series.xAxis,\r\n isDateTime = xAxis && xAxis.options.type === \"datetime\",\r\n headerFormat = tooltipOptions.headerFormat,\r\n closestPointRange = xAxis && xAxis.closestPointRange,\r\n n;\r\n\r\n // Guess the best date format based on the closest point distance (#568)\r\n if (isDateTime && !xDateFormat) {\r\n if (closestPointRange) {\r\n for (n in timeUnits) {\r\n if (timeUnits[n] >= closestPointRange) {\r\n xDateFormat = dateTimeLabelFormats[n];\r\n break;\r\n }\r\n }\r\n }\r\n else {\r\n xDateFormat = dateTimeLabelFormats.day;\r\n }\r\n }\r\n\r\n // Insert the header date format if any\r\n if (isDateTime && xDateFormat && isNumber(point.key)) {\r\n headerFormat = headerFormat.replace(\r\n \"{point.key}\",\r\n \"{point.key:\" + xDateFormat + \"}\"\r\n );\r\n }\r\n\r\n return format(headerFormat, {\r\n point: point,\r\n series: series\r\n });\r\n },\r\n\r\n /**\r\n * Series mouse over handler\r\n */\r\n onMouseOver: function() {\r\n var series = this,\r\n chart = series.chart,\r\n hoverSeries = chart.hoverSeries;\r\n\r\n // set normal state to previous series\r\n if (hoverSeries && hoverSeries !== series) {\r\n hoverSeries.onMouseOut();\r\n }\r\n\r\n // trigger the event, but to save processing time,\r\n // only if defined\r\n if (series.options.events.mouseOver) {\r\n fireEvent(series, \"mouseOver\");\r\n }\r\n\r\n // hover this\r\n series.setState(HOVER_STATE);\r\n chart.hoverSeries = series;\r\n },\r\n\r\n /**\r\n * Series mouse out handler\r\n */\r\n onMouseOut: function() {\r\n // trigger the event only if listeners exist\r\n var series = this,\r\n options = series.options,\r\n chart = series.chart,\r\n tooltip = chart.tooltip,\r\n hoverPoint = chart.hoverPoint;\r\n\r\n // trigger mouse out on the point, which must be in this series\r\n if (hoverPoint) {\r\n hoverPoint.onMouseOut();\r\n }\r\n\r\n // fire the mouse out event\r\n if (series && options.events.mouseOut) {\r\n fireEvent(series, \"mouseOut\");\r\n }\r\n\r\n // hide the tooltip\r\n if (\r\n tooltip &&\r\n !options.stickyTracking &&\r\n (!tooltip.shared || series.noSharedTooltip)\r\n ) {\r\n tooltip.hide();\r\n }\r\n\r\n // set normal state\r\n series.setState();\r\n chart.hoverSeries = null;\r\n },\r\n\r\n /**\r\n * Animate in the series\r\n */\r\n animate: function(init) {\r\n var series = this,\r\n chart = series.chart,\r\n renderer = chart.renderer,\r\n clipRect,\r\n markerClipRect,\r\n animation = series.options.animation,\r\n clipBox = chart.clipBox,\r\n inverted = chart.inverted,\r\n sharedClipKey;\r\n\r\n // Animation option is set to true\r\n if (animation && !isObject(animation)) {\r\n animation = defaultPlotOptions[series.type].animation;\r\n }\r\n sharedClipKey = \"_sharedClip\" + animation.duration + animation.easing;\r\n\r\n // Initialize the animation. Set up the clipping rectangle.\r\n if (init) {\r\n // If a clipping rectangle with the same properties is currently present in the chart, use that.\r\n clipRect = chart[sharedClipKey];\r\n markerClipRect = chart[sharedClipKey + \"m\"];\r\n if (!clipRect) {\r\n chart[sharedClipKey] = clipRect = renderer.clipRect(\r\n extend(clipBox, { width: 0 })\r\n );\r\n\r\n chart[sharedClipKey + \"m\"] = markerClipRect = renderer.clipRect(\r\n -99, // include the width of the first marker\r\n inverted ? -chart.plotLeft : -chart.plotTop,\r\n 99,\r\n inverted ? chart.chartWidth : chart.chartHeight\r\n );\r\n }\r\n series.group.clip(clipRect);\r\n series.markerGroup.clip(markerClipRect);\r\n series.sharedClipKey = sharedClipKey;\r\n\r\n // Run the animation\r\n }\r\n else {\r\n clipRect = chart[sharedClipKey];\r\n if (clipRect) {\r\n clipRect.animate(\r\n {\r\n width: chart.plotSizeX\r\n },\r\n animation\r\n );\r\n chart[sharedClipKey + \"m\"].animate(\r\n {\r\n width: chart.plotSizeX + 99\r\n },\r\n animation\r\n );\r\n }\r\n\r\n // Delete this function to allow it only once\r\n series.animate = null;\r\n\r\n // Call the afterAnimate function on animation complete (but don't overwrite the animation.complete option\r\n // which should be available to the user).\r\n series.animationTimeout = setTimeout(function() {\r\n series.afterAnimate();\r\n }, animation.duration);\r\n }\r\n },\r\n\r\n /**\r\n * This runs after animation to land on the final plot clipping\r\n */\r\n afterAnimate: function() {\r\n var chart = this.chart,\r\n sharedClipKey = this.sharedClipKey,\r\n group = this.group;\r\n\r\n if (group && this.options.clip !== false) {\r\n group.clip(chart.clipRect);\r\n this.markerGroup.clip(); // no clip\r\n }\r\n\r\n // Remove the shared clipping rectancgle when all series are shown\r\n setTimeout(function() {\r\n if (sharedClipKey && chart[sharedClipKey]) {\r\n chart[sharedClipKey] = chart[sharedClipKey].destroy();\r\n chart[sharedClipKey + \"m\"] = chart[sharedClipKey + \"m\"].destroy();\r\n }\r\n }, 100);\r\n },\r\n\r\n /**\r\n * Draw the markers\r\n */\r\n drawPoints: function() {\r\n var series = this,\r\n pointAttr,\r\n points = series.points,\r\n chart = series.chart,\r\n plotX,\r\n plotY,\r\n i,\r\n point,\r\n radius,\r\n symbol,\r\n isImage,\r\n graphic,\r\n options = series.options,\r\n seriesMarkerOptions = options.marker,\r\n pointMarkerOptions,\r\n enabled,\r\n isInside,\r\n markerGroup = series.markerGroup;\r\n\r\n if (seriesMarkerOptions.enabled || series._hasPointMarkers) {\r\n i = points.length;\r\n while (i--) {\r\n point = points[i];\r\n plotX = mathFloor(point.plotX); // #1843\r\n plotY = point.plotY;\r\n graphic = point.graphic;\r\n pointMarkerOptions = point.marker || {};\r\n enabled =\r\n (seriesMarkerOptions.enabled &&\r\n pointMarkerOptions.enabled === UNDEFINED) ||\r\n pointMarkerOptions.enabled;\r\n isInside = chart.isInsidePlot(\r\n mathRound(plotX),\r\n plotY,\r\n chart.inverted\r\n ); // #1858\r\n\r\n // only draw the point if y is defined\r\n if (\r\n enabled &&\r\n plotY !== UNDEFINED &&\r\n !isNaN(plotY) &&\r\n point.y !== null\r\n ) {\r\n // shortcuts\r\n pointAttr =\r\n point.pointAttr[point.selected ? SELECT_STATE : NORMAL_STATE];\r\n radius = pointAttr.r;\r\n symbol = pick(pointMarkerOptions.symbol, series.symbol);\r\n isImage = symbol.indexOf(\"url\") === 0;\r\n\r\n if (graphic) {\r\n // update\r\n graphic\r\n .attr({\r\n // Since the marker group isn't clipped, each individual marker must be toggled\r\n visibility: isInside ? (hasSVG ? \"inherit\" : VISIBLE) : HIDDEN\r\n })\r\n .animate(\r\n extend(\r\n {\r\n x: plotX - radius,\r\n y: plotY - radius\r\n },\r\n graphic.symbolName\r\n ? {\r\n // don't apply to image symbols #507\r\n width: 2 * radius,\r\n height: 2 * radius\r\n }\r\n : {}\r\n )\r\n );\r\n }\r\n else if (isInside && (radius > 0 || isImage)) {\r\n point.graphic = graphic = chart.renderer\r\n .symbol(\r\n symbol,\r\n plotX - radius,\r\n plotY - radius,\r\n 2 * radius,\r\n 2 * radius\r\n )\r\n .attr(pointAttr)\r\n .add(markerGroup);\r\n }\r\n }\r\n else if (graphic) {\r\n point.graphic = graphic.destroy(); // #1269\r\n }\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Convert state properties from API naming conventions to SVG attributes\r\n *\r\n * @param {Object} options API options object\r\n * @param {Object} base1 SVG attribute object to inherit from\r\n * @param {Object} base2 Second level SVG attribute object to inherit from\r\n */\r\n convertAttribs: function(options, base1, base2, base3) {\r\n var conversion = this.pointAttrToOptions,\r\n attr,\r\n option,\r\n obj = {};\r\n\r\n options = options || {};\r\n base1 = base1 || {};\r\n base2 = base2 || {};\r\n base3 = base3 || {};\r\n\r\n for (attr in conversion) {\r\n option = conversion[attr];\r\n obj[attr] = pick(\r\n options[option],\r\n base1[attr],\r\n base2[attr],\r\n base3[attr]\r\n );\r\n }\r\n return obj;\r\n },\r\n\r\n /**\r\n * Get the state attributes. Each series type has its own set of attributes\r\n * that are allowed to change on a point's state change. Series wide attributes are stored for\r\n * all series, and additionally point specific attributes are stored for all\r\n * points with individual marker options. If such options are not defined for the point,\r\n * a reference to the series wide attributes is stored in point.pointAttr.\r\n */\r\n getAttribs: function() {\r\n var series = this,\r\n seriesOptions = series.options,\r\n normalOptions = defaultPlotOptions[series.type].marker\r\n ? seriesOptions.marker\r\n : seriesOptions,\r\n stateOptions = normalOptions.states,\r\n stateOptionsHover = stateOptions[HOVER_STATE],\r\n pointStateOptionsHover,\r\n seriesColor = series.color,\r\n normalDefaults = {\r\n stroke: seriesColor,\r\n fill: seriesColor\r\n },\r\n points = series.points || [], // #927\r\n i,\r\n point,\r\n seriesPointAttr = [],\r\n pointAttr,\r\n pointAttrToOptions = series.pointAttrToOptions,\r\n hasPointSpecificOptions,\r\n negativeColor = seriesOptions.negativeColor,\r\n defaultLineColor = normalOptions.lineColor,\r\n key;\r\n\r\n // series type specific modifications\r\n if (seriesOptions.marker) {\r\n // line, spline, area, areaspline, scatter\r\n\r\n // if no hover radius is given, default to normal radius + 2\r\n stateOptionsHover.radius =\r\n stateOptionsHover.radius || normalOptions.radius + 2;\r\n stateOptionsHover.lineWidth =\r\n stateOptionsHover.lineWidth || normalOptions.lineWidth + 1;\r\n }\r\n else {\r\n // column, bar, pie\r\n\r\n // if no hover color is given, brighten the normal color\r\n stateOptionsHover.color =\r\n stateOptionsHover.color ||\r\n Color(stateOptionsHover.color || seriesColor)\r\n .brighten(stateOptionsHover.brightness)\r\n .get();\r\n }\r\n\r\n // general point attributes for the series normal state\r\n seriesPointAttr[NORMAL_STATE] = series.convertAttribs(\r\n normalOptions,\r\n normalDefaults\r\n );\r\n\r\n // HOVER_STATE and SELECT_STATE states inherit from normal state except the default radius\r\n each([HOVER_STATE, SELECT_STATE], function(state) {\r\n seriesPointAttr[state] = series.convertAttribs(\r\n stateOptions[state],\r\n seriesPointAttr[NORMAL_STATE]\r\n );\r\n });\r\n\r\n // set it\r\n series.pointAttr = seriesPointAttr;\r\n\r\n // Generate the point-specific attribute collections if specific point\r\n // options are given. If not, create a referance to the series wide point\r\n // attributes\r\n i = points.length;\r\n while (i--) {\r\n point = points[i];\r\n normalOptions =\r\n (point.options && point.options.marker) || point.options;\r\n if (normalOptions && normalOptions.enabled === false) {\r\n normalOptions.radius = 0;\r\n }\r\n\r\n if (point.negative && negativeColor) {\r\n point.color = point.fillColor = negativeColor;\r\n }\r\n\r\n hasPointSpecificOptions = seriesOptions.colorByPoint || point.color; // #868\r\n\r\n // check if the point has specific visual options\r\n if (point.options) {\r\n for (key in pointAttrToOptions) {\r\n if (defined(normalOptions[pointAttrToOptions[key]])) {\r\n hasPointSpecificOptions = true;\r\n }\r\n }\r\n }\r\n\r\n // a specific marker config object is defined for the individual point:\r\n // create it's own attribute collection\r\n if (hasPointSpecificOptions) {\r\n normalOptions = normalOptions || {};\r\n pointAttr = [];\r\n stateOptions = normalOptions.states || {}; // reassign for individual point\r\n pointStateOptionsHover = stateOptions[HOVER_STATE] =\r\n stateOptions[HOVER_STATE] || {};\r\n\r\n // Handle colors for column and pies\r\n if (!seriesOptions.marker) {\r\n // column, bar, point\r\n // if no hover color is given, brighten the normal color\r\n pointStateOptionsHover.color = Color(\r\n pointStateOptionsHover.color || point.color\r\n )\r\n .brighten(\r\n pointStateOptionsHover.brightness ||\r\n stateOptionsHover.brightness\r\n )\r\n .get();\r\n }\r\n\r\n // normal point state inherits series wide normal state\r\n pointAttr[NORMAL_STATE] = series.convertAttribs(\r\n extend(\r\n {\r\n color: point.color, // #868\r\n fillColor: point.color, // Individual point color or negative color markers (#2219)\r\n lineColor: defaultLineColor === null ? point.color : UNDEFINED // Bubbles take point color, line markers use white\r\n },\r\n normalOptions\r\n ),\r\n seriesPointAttr[NORMAL_STATE]\r\n );\r\n\r\n // inherit from point normal and series hover\r\n pointAttr[HOVER_STATE] = series.convertAttribs(\r\n stateOptions[HOVER_STATE],\r\n seriesPointAttr[HOVER_STATE],\r\n pointAttr[NORMAL_STATE]\r\n );\r\n\r\n // inherit from point normal and series hover\r\n pointAttr[SELECT_STATE] = series.convertAttribs(\r\n stateOptions[SELECT_STATE],\r\n seriesPointAttr[SELECT_STATE],\r\n pointAttr[NORMAL_STATE]\r\n );\r\n\r\n // no marker config object is created: copy a reference to the series-wide\r\n // attribute collection\r\n }\r\n else {\r\n pointAttr = seriesPointAttr;\r\n }\r\n\r\n point.pointAttr = pointAttr;\r\n }\r\n },\r\n /**\r\n * Update the series with a new set of options\r\n */\r\n update: function(newOptions, redraw) {\r\n var chart = this.chart,\r\n // must use user options when changing type because this.options is merged\r\n // in with type specific plotOptions\r\n oldOptions = this.userOptions,\r\n oldType = this.type,\r\n proto = seriesTypes[oldType].prototype,\r\n n;\r\n\r\n // Do the merge, with some forced options\r\n newOptions = merge(\r\n oldOptions,\r\n {\r\n animation: false,\r\n index: this.index,\r\n pointStart: this.xData[0] // when updating after addPoint\r\n },\r\n { data: this.options.data },\r\n newOptions\r\n );\r\n\r\n // Destroy the series and reinsert methods from the type prototype\r\n this.remove(false);\r\n for (n in proto) {\r\n // Overwrite series-type specific methods (#2270)\r\n if (proto.hasOwnProperty(n)) {\r\n this[n] = UNDEFINED;\r\n }\r\n }\r\n extend(this, seriesTypes[newOptions.type || oldType].prototype);\r\n\r\n this.init(chart, newOptions);\r\n if (pick(redraw, true)) {\r\n chart.redraw(false);\r\n }\r\n },\r\n\r\n /**\r\n * Clear DOM objects and free up memory\r\n */\r\n destroy: function() {\r\n var series = this,\r\n chart = series.chart,\r\n issue134 = /AppleWebKit\\/533/.test(userAgent),\r\n destroy,\r\n i,\r\n data = series.data || [],\r\n point,\r\n prop,\r\n axis;\r\n\r\n // add event hook\r\n fireEvent(series, \"destroy\");\r\n\r\n // remove all events\r\n removeEvent(series);\r\n\r\n // erase from axes\r\n each([\"xAxis\", \"yAxis\"], function(AXIS) {\r\n axis = series[AXIS];\r\n if (axis) {\r\n erase(axis.series, series);\r\n axis.isDirty = axis.forceRedraw = true;\r\n axis.stacks = {}; // Rebuild stacks when updating (#2229)\r\n }\r\n });\r\n\r\n // remove legend items\r\n if (series.legendItem) {\r\n series.chart.legend.destroyItem(series);\r\n }\r\n\r\n // destroy all points with their elements\r\n i = data.length;\r\n while (i--) {\r\n point = data[i];\r\n if (point && point.destroy) {\r\n point.destroy();\r\n }\r\n }\r\n series.points = null;\r\n\r\n // Clear the animation timeout if we are destroying the series during initial animation\r\n clearTimeout(series.animationTimeout);\r\n\r\n // destroy all SVGElements associated to the series\r\n each(\r\n [\r\n \"area\",\r\n \"graph\",\r\n \"dataLabelsGroup\",\r\n \"group\",\r\n \"markerGroup\",\r\n \"tracker\",\r\n \"graphNeg\",\r\n \"areaNeg\",\r\n \"posClip\",\r\n \"negClip\"\r\n ],\r\n function(prop) {\r\n if (series[prop]) {\r\n // issue 134 workaround\r\n destroy = issue134 && prop === \"group\" ? \"hide\" : \"destroy\";\r\n\r\n series[prop][destroy]();\r\n }\r\n }\r\n );\r\n\r\n // remove from hoverSeries\r\n if (chart.hoverSeries === series) {\r\n chart.hoverSeries = null;\r\n }\r\n erase(chart.series, series);\r\n\r\n // clear all members\r\n for (prop in series) {\r\n delete series[prop];\r\n }\r\n },\r\n\r\n /**\r\n * Draw the data labels\r\n */\r\n drawDataLabels: function() {\r\n var series = this,\r\n seriesOptions = series.options,\r\n cursor = seriesOptions.cursor,\r\n options = seriesOptions.dataLabels,\r\n points = series.points,\r\n pointOptions,\r\n generalOptions,\r\n str,\r\n dataLabelsGroup;\r\n\r\n if (options.enabled || series._hasPointLabels) {\r\n // Process default alignment of data labels for columns\r\n if (series.dlProcessOptions) {\r\n series.dlProcessOptions(options);\r\n }\r\n\r\n // Create a separate group for the data labels to avoid rotation\r\n dataLabelsGroup = series.plotGroup(\r\n \"dataLabelsGroup\",\r\n \"data-labels\",\r\n series.visible ? VISIBLE : HIDDEN,\r\n options.zIndex || 6\r\n );\r\n\r\n // Make the labels for each point\r\n generalOptions = options;\r\n each(points, function(point) {\r\n var enabled,\r\n dataLabel = point.dataLabel,\r\n labelConfig,\r\n attr,\r\n name,\r\n rotation,\r\n connector = point.connector,\r\n isNew = true;\r\n\r\n // Determine if each data label is enabled\r\n pointOptions = point.options && point.options.dataLabels;\r\n enabled = pick(\r\n pointOptions && pointOptions.enabled,\r\n generalOptions.enabled\r\n ); // #2282\r\n\r\n // If the point is outside the plot area, destroy it. #678, #820\r\n if (dataLabel && !enabled) {\r\n point.dataLabel = dataLabel.destroy();\r\n\r\n // Individual labels are disabled if the are explicitly disabled\r\n // in the point options, or if they fall outside the plot area.\r\n }\r\n else if (enabled) {\r\n // Create individual options structure that can be extended without\r\n // affecting others\r\n options = merge(generalOptions, pointOptions);\r\n\r\n rotation = options.rotation;\r\n\r\n // Get the string\r\n labelConfig = point.getLabelConfig();\r\n str = options.format\r\n ? format(options.format, labelConfig)\r\n : options.formatter.call(labelConfig, options);\r\n\r\n // Determine the color\r\n options.style.color = pick(\r\n options.color,\r\n options.style.color,\r\n series.color,\r\n \"black\"\r\n );\r\n\r\n // update existing label\r\n if (dataLabel) {\r\n if (defined(str)) {\r\n dataLabel.attr({\r\n text: str\r\n });\r\n isNew = false;\r\n }\r\n else {\r\n // #1437 - the label is shown conditionally\r\n point.dataLabel = dataLabel = dataLabel.destroy();\r\n if (connector) {\r\n point.connector = connector.destroy();\r\n }\r\n }\r\n\r\n // create new label\r\n }\r\n else if (defined(str)) {\r\n attr = {\r\n //align: align,\r\n fill: options.backgroundColor,\r\n stroke: options.borderColor,\r\n \"stroke-width\": options.borderWidth,\r\n r: options.borderRadius || 0,\r\n rotation: rotation,\r\n padding: options.padding,\r\n zIndex: 1\r\n };\r\n // Remove unused attributes (#947)\r\n for (name in attr) {\r\n if (attr[name] === UNDEFINED) {\r\n delete attr[name];\r\n }\r\n }\r\n\r\n dataLabel = point.dataLabel = series.chart.renderer[\r\n rotation ? \"text\" : \"label\"\r\n ](\r\n // labels don't support rotation\r\n str,\r\n 0,\r\n -999,\r\n null,\r\n null,\r\n null,\r\n options.useHTML\r\n )\r\n .attr(attr)\r\n .css(extend(options.style, cursor && { cursor: cursor }))\r\n .add(dataLabelsGroup)\r\n .shadow(options.shadow);\r\n }\r\n\r\n if (dataLabel) {\r\n // Now the data label is created and placed at 0,0, so we need to align it\r\n series.alignDataLabel(point, dataLabel, options, null, isNew);\r\n }\r\n }\r\n });\r\n }\r\n },\r\n\r\n /**\r\n * Align each individual data label\r\n */\r\n alignDataLabel: function(point, dataLabel, options, alignTo, isNew) {\r\n var chart = this.chart,\r\n inverted = chart.inverted,\r\n plotX = pick(point.plotX, -999),\r\n plotY = pick(point.plotY, -999),\r\n bBox = dataLabel.getBBox(),\r\n visible =\r\n this.visible &&\r\n chart.isInsidePlot(point.plotX, point.plotY, inverted),\r\n alignAttr; // the final position;\r\n\r\n if (visible) {\r\n // The alignment box is a singular point\r\n alignTo = extend(\r\n {\r\n x: inverted ? chart.plotWidth - plotY : plotX,\r\n y: mathRound(inverted ? chart.plotHeight - plotX : plotY),\r\n width: 0,\r\n height: 0\r\n },\r\n alignTo\r\n );\r\n\r\n // Add the text size for alignment calculation\r\n extend(options, {\r\n width: bBox.width,\r\n height: bBox.height\r\n });\r\n\r\n // Allow a hook for changing alignment in the last moment, then do the alignment\r\n if (options.rotation) {\r\n // Fancy box alignment isn't supported for rotated text\r\n alignAttr = {\r\n align: options.align,\r\n x: alignTo.x + options.x + alignTo.width / 2,\r\n y: alignTo.y + options.y + alignTo.height / 2\r\n };\r\n dataLabel[isNew ? \"attr\" : \"animate\"](alignAttr);\r\n }\r\n else {\r\n dataLabel.align(options, null, alignTo);\r\n alignAttr = dataLabel.alignAttr;\r\n\r\n // Handle justify or crop\r\n if (pick(options.overflow, \"justify\") === \"justify\") {\r\n this.justifyDataLabel(\r\n dataLabel,\r\n options,\r\n alignAttr,\r\n bBox,\r\n alignTo,\r\n isNew\r\n );\r\n }\r\n else if (pick(options.crop, true)) {\r\n // Now check that the data label is within the plot area\r\n visible =\r\n chart.isInsidePlot(alignAttr.x, alignAttr.y) &&\r\n chart.isInsidePlot(\r\n alignAttr.x + bBox.width,\r\n alignAttr.y + bBox.height\r\n );\r\n }\r\n }\r\n }\r\n\r\n // Show or hide based on the final aligned position\r\n if (!visible) {\r\n dataLabel.attr({ y: -999 });\r\n }\r\n },\r\n\r\n /**\r\n * If data labels fall partly outside the plot area, align them back in, in a way that\r\n * doesn't hide the point.\r\n */\r\n justifyDataLabel: function(\r\n dataLabel,\r\n options,\r\n alignAttr,\r\n bBox,\r\n alignTo,\r\n isNew\r\n ) {\r\n var chart = this.chart,\r\n align = options.align,\r\n verticalAlign = options.verticalAlign,\r\n off,\r\n justified;\r\n\r\n // Off left\r\n off = alignAttr.x;\r\n if (off < 0) {\r\n if (align === \"right\") {\r\n options.align = \"left\";\r\n }\r\n else {\r\n options.x = -off;\r\n }\r\n justified = true;\r\n }\r\n\r\n // Off right\r\n off = alignAttr.x + bBox.width;\r\n if (off > chart.plotWidth) {\r\n if (align === \"left\") {\r\n options.align = \"right\";\r\n }\r\n else {\r\n options.x = chart.plotWidth - off;\r\n }\r\n justified = true;\r\n }\r\n\r\n // Off top\r\n off = alignAttr.y;\r\n if (off < 0) {\r\n if (verticalAlign === \"bottom\") {\r\n options.verticalAlign = \"top\";\r\n }\r\n else {\r\n options.y = -off;\r\n }\r\n justified = true;\r\n }\r\n\r\n // Off bottom\r\n off = alignAttr.y + bBox.height;\r\n if (off > chart.plotHeight) {\r\n if (verticalAlign === \"top\") {\r\n options.verticalAlign = \"bottom\";\r\n }\r\n else {\r\n options.y = chart.plotHeight - off;\r\n }\r\n justified = true;\r\n }\r\n\r\n if (justified) {\r\n dataLabel.placed = !isNew;\r\n dataLabel.align(options, null, alignTo);\r\n }\r\n },\r\n\r\n /**\r\n * Return the graph path of a segment\r\n */\r\n getSegmentPath: function(segment) {\r\n var series = this,\r\n segmentPath = [],\r\n step = series.options.step;\r\n\r\n // build the segment line\r\n each(segment, function(point, i) {\r\n var plotX = point.plotX,\r\n plotY = point.plotY,\r\n lastPoint;\r\n\r\n if (series.getPointSpline) {\r\n // generate the spline as defined in the SplineSeries object\r\n segmentPath.push.apply(\r\n segmentPath,\r\n series.getPointSpline(segment, point, i)\r\n );\r\n }\r\n else {\r\n // moveTo or lineTo\r\n segmentPath.push(i ? L : M);\r\n\r\n // step line?\r\n if (step && i) {\r\n lastPoint = segment[i - 1];\r\n if (step === \"right\") {\r\n segmentPath.push(lastPoint.plotX, plotY);\r\n }\r\n else if (step === \"center\") {\r\n segmentPath.push(\r\n (lastPoint.plotX + plotX) / 2,\r\n lastPoint.plotY,\r\n (lastPoint.plotX + plotX) / 2,\r\n plotY\r\n );\r\n }\r\n else {\r\n segmentPath.push(plotX, lastPoint.plotY);\r\n }\r\n }\r\n\r\n // normal line to next point\r\n segmentPath.push(point.plotX, point.plotY);\r\n }\r\n });\r\n\r\n return segmentPath;\r\n },\r\n\r\n /**\r\n * Get the graph path\r\n */\r\n getGraphPath: function() {\r\n var series = this,\r\n graphPath = [],\r\n segmentPath,\r\n singlePoints = []; // used in drawTracker\r\n\r\n // Divide into segments and build graph and area paths\r\n each(series.segments, function(segment) {\r\n segmentPath = series.getSegmentPath(segment);\r\n\r\n // add the segment to the graph, or a single point for tracking\r\n if (segment.length > 1) {\r\n graphPath = graphPath.concat(segmentPath);\r\n }\r\n else {\r\n singlePoints.push(segment[0]);\r\n }\r\n });\r\n\r\n // Record it for use in drawGraph and drawTracker, and return graphPath\r\n series.singlePoints = singlePoints;\r\n series.graphPath = graphPath;\r\n\r\n return graphPath;\r\n },\r\n\r\n /**\r\n * Draw the actual graph\r\n */\r\n drawGraph: function() {\r\n var series = this,\r\n options = this.options,\r\n props = [[\"graph\", options.lineColor || this.color]],\r\n lineWidth = options.lineWidth,\r\n dashStyle = options.dashStyle,\r\n roundCap = options.linecap !== \"square\",\r\n graphPath = this.getGraphPath(),\r\n negativeColor = options.negativeColor;\r\n\r\n if (negativeColor) {\r\n props.push([\"graphNeg\", negativeColor]);\r\n }\r\n\r\n // draw the graph\r\n each(props, function(prop, i) {\r\n var graphKey = prop[0],\r\n graph = series[graphKey],\r\n attribs;\r\n\r\n if (graph) {\r\n stop(graph); // cancel running animations, #459\r\n graph.animate({ d: graphPath });\r\n }\r\n else if (lineWidth && graphPath.length) {\r\n // #1487\r\n attribs = {\r\n stroke: prop[1],\r\n \"stroke-width\": lineWidth,\r\n zIndex: 1 // #1069\r\n };\r\n if (dashStyle) {\r\n attribs.dashstyle = dashStyle;\r\n }\r\n else if (roundCap) {\r\n attribs[\"stroke-linecap\"] = attribs[\"stroke-linejoin\"] = \"round\";\r\n }\r\n\r\n series[graphKey] = series.chart.renderer\r\n .path(graphPath)\r\n .attr(attribs)\r\n .add(series.group)\r\n .shadow(!i && options.shadow);\r\n }\r\n });\r\n },\r\n\r\n /**\r\n * Clip the graphs into the positive and negative coloured graphs\r\n */\r\n clipNeg: function() {\r\n var options = this.options,\r\n chart = this.chart,\r\n renderer = chart.renderer,\r\n negativeColor = options.negativeColor || options.negativeFillColor,\r\n translatedThreshold,\r\n posAttr,\r\n negAttr,\r\n graph = this.graph,\r\n area = this.area,\r\n posClip = this.posClip,\r\n negClip = this.negClip,\r\n chartWidth = chart.chartWidth,\r\n chartHeight = chart.chartHeight,\r\n chartSizeMax = mathMax(chartWidth, chartHeight),\r\n yAxis = this.yAxis,\r\n above,\r\n below;\r\n\r\n if (negativeColor && (graph || area)) {\r\n translatedThreshold = mathRound(\r\n yAxis.toPixels(options.threshold || 0, true)\r\n );\r\n above = {\r\n x: 0,\r\n y: 0,\r\n width: chartSizeMax,\r\n height: translatedThreshold\r\n };\r\n below = {\r\n x: 0,\r\n y: translatedThreshold,\r\n width: chartSizeMax,\r\n height: chartSizeMax\r\n };\r\n\r\n if (chart.inverted) {\r\n above.height = below.y = chart.plotWidth - translatedThreshold;\r\n if (renderer.isVML) {\r\n above = {\r\n x: chart.plotWidth - translatedThreshold - chart.plotLeft,\r\n y: 0,\r\n width: chartWidth,\r\n height: chartHeight\r\n };\r\n below = {\r\n x: translatedThreshold + chart.plotLeft - chartWidth,\r\n y: 0,\r\n width: chart.plotLeft + translatedThreshold,\r\n height: chartWidth\r\n };\r\n }\r\n }\r\n\r\n if (yAxis.reversed) {\r\n posAttr = below;\r\n negAttr = above;\r\n }\r\n else {\r\n posAttr = above;\r\n negAttr = below;\r\n }\r\n\r\n if (posClip) {\r\n // update\r\n posClip.animate(posAttr);\r\n negClip.animate(negAttr);\r\n }\r\n else {\r\n this.posClip = posClip = renderer.clipRect(posAttr);\r\n this.negClip = negClip = renderer.clipRect(negAttr);\r\n\r\n if (graph && this.graphNeg) {\r\n graph.clip(posClip);\r\n this.graphNeg.clip(negClip);\r\n }\r\n\r\n if (area) {\r\n area.clip(posClip);\r\n this.areaNeg.clip(negClip);\r\n }\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Initialize and perform group inversion on series.group and series.markerGroup\r\n */\r\n invertGroups: function() {\r\n var series = this,\r\n chart = series.chart;\r\n\r\n // Pie, go away (#1736)\r\n if (!series.xAxis) {\r\n return;\r\n }\r\n\r\n // A fixed size is needed for inversion to work\r\n function setInvert() {\r\n var size = {\r\n width: series.yAxis.len,\r\n height: series.xAxis.len\r\n };\r\n\r\n each([\"group\", \"markerGroup\"], function(groupName) {\r\n if (series[groupName]) {\r\n series[groupName].attr(size).invert();\r\n }\r\n });\r\n }\r\n\r\n addEvent(chart, \"resize\", setInvert); // do it on resize\r\n addEvent(series, \"destroy\", function() {\r\n removeEvent(chart, \"resize\", setInvert);\r\n });\r\n\r\n // Do it now\r\n setInvert(); // do it now\r\n\r\n // On subsequent render and redraw, just do setInvert without setting up events again\r\n series.invertGroups = setInvert;\r\n },\r\n\r\n /**\r\n * General abstraction for creating plot groups like series.group, series.dataLabelsGroup and\r\n * series.markerGroup. On subsequent calls, the group will only be adjusted to the updated plot size.\r\n */\r\n plotGroup: function(prop, name, visibility, zIndex, parent) {\r\n var group = this[prop],\r\n isNew = !group;\r\n\r\n // Generate it on first call\r\n if (isNew) {\r\n this[prop] = group = this.chart.renderer\r\n .g(name)\r\n .attr({\r\n visibility: visibility,\r\n zIndex: zIndex || 0.1 // IE8 needs this\r\n })\r\n .add(parent);\r\n }\r\n // Place it on first and subsequent (redraw) calls\r\n group[isNew ? \"attr\" : \"animate\"](this.getPlotBox());\r\n return group;\r\n },\r\n\r\n /**\r\n * Get the translation and scale for the plot area of this series\r\n */\r\n getPlotBox: function() {\r\n return {\r\n translateX: this.xAxis ? this.xAxis.left : this.chart.plotLeft,\r\n translateY: this.yAxis ? this.yAxis.top : this.chart.plotTop,\r\n scaleX: 1, // #1623\r\n scaleY: 1\r\n };\r\n },\r\n\r\n /**\r\n * Render the graph and markers\r\n */\r\n render: function() {\r\n var series = this,\r\n chart = series.chart,\r\n group,\r\n options = series.options,\r\n animation = options.animation,\r\n doAnimation = animation && !!series.animate && chart.renderer.isSVG, // this animation doesn't work in IE8 quirks when the group div is hidden,\r\n // and looks bad in other oldIE\r\n visibility = series.visible ? VISIBLE : HIDDEN,\r\n zIndex = options.zIndex,\r\n hasRendered = series.hasRendered,\r\n chartSeriesGroup = chart.seriesGroup;\r\n\r\n // the group\r\n group = series.plotGroup(\r\n \"group\",\r\n \"series\",\r\n visibility,\r\n zIndex,\r\n chartSeriesGroup\r\n );\r\n\r\n series.markerGroup = series.plotGroup(\r\n \"markerGroup\",\r\n \"markers\",\r\n visibility,\r\n zIndex,\r\n chartSeriesGroup\r\n );\r\n\r\n // initiate the animation\r\n if (doAnimation) {\r\n series.animate(true);\r\n }\r\n\r\n // cache attributes for shapes\r\n series.getAttribs();\r\n\r\n // SVGRenderer needs to know this before drawing elements (#1089, #1795)\r\n group.inverted = series.isCartesian ? chart.inverted : false;\r\n\r\n // draw the graph if any\r\n if (series.drawGraph) {\r\n series.drawGraph();\r\n series.clipNeg();\r\n }\r\n\r\n // draw the data labels (inn pies they go before the points)\r\n series.drawDataLabels();\r\n\r\n // draw the points\r\n series.drawPoints();\r\n\r\n // draw the mouse tracking area\r\n if (series.options.enableMouseTracking !== false) {\r\n series.drawTracker();\r\n }\r\n\r\n // Handle inverted series and tracker groups\r\n if (chart.inverted) {\r\n series.invertGroups();\r\n }\r\n\r\n // Initial clipping, must be defined after inverting groups for VML\r\n if (options.clip !== false && !series.sharedClipKey && !hasRendered) {\r\n group.clip(chart.clipRect);\r\n }\r\n\r\n // Run the animation\r\n if (doAnimation) {\r\n series.animate();\r\n }\r\n else if (!hasRendered) {\r\n series.afterAnimate();\r\n }\r\n\r\n series.isDirty = series.isDirtyData = false; // means data is in accordance with what you see\r\n // (See #322) series.isDirty = series.isDirtyData = false; // means data is in accordance with what you see\r\n series.hasRendered = true;\r\n },\r\n\r\n /**\r\n * Redraw the series after an update in the axes.\r\n */\r\n redraw: function() {\r\n var series = this,\r\n chart = series.chart,\r\n wasDirtyData = series.isDirtyData, // cache it here as it is set to false in render, but used after\r\n group = series.group,\r\n xAxis = series.xAxis,\r\n yAxis = series.yAxis;\r\n\r\n // reposition on resize\r\n if (group) {\r\n if (chart.inverted) {\r\n group.attr({\r\n width: chart.plotWidth,\r\n height: chart.plotHeight\r\n });\r\n }\r\n\r\n group.animate({\r\n translateX: pick(xAxis && xAxis.left, chart.plotLeft),\r\n translateY: pick(yAxis && yAxis.top, chart.plotTop)\r\n });\r\n }\r\n\r\n series.translate();\r\n series.setTooltipPoints(true);\r\n\r\n series.render();\r\n if (wasDirtyData) {\r\n fireEvent(series, \"updatedData\");\r\n }\r\n },\r\n\r\n /**\r\n * Set the state of the graph\r\n */\r\n setState: function(state) {\r\n var series = this,\r\n options = series.options,\r\n graph = series.graph,\r\n graphNeg = series.graphNeg,\r\n stateOptions = options.states,\r\n lineWidth = options.lineWidth,\r\n attribs;\r\n\r\n state = state || NORMAL_STATE;\r\n\r\n if (series.state !== state) {\r\n series.state = state;\r\n\r\n if (stateOptions[state] && stateOptions[state].enabled === false) {\r\n return;\r\n }\r\n\r\n if (state) {\r\n lineWidth = stateOptions[state].lineWidth || lineWidth + 1;\r\n }\r\n\r\n if (graph && !graph.dashstyle) {\r\n // hover is turned off for dashed lines in VML\r\n attribs = {\r\n \"stroke-width\": lineWidth\r\n };\r\n // use attr because animate will cause any other animation on the graph to stop\r\n graph.attr(attribs);\r\n if (graphNeg) {\r\n graphNeg.attr(attribs);\r\n }\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Set the visibility of the graph\r\n *\r\n * @param vis {Boolean} True to show the series, false to hide. If UNDEFINED,\r\n * the visibility is toggled.\r\n */\r\n setVisible: function(vis, redraw) {\r\n var series = this,\r\n chart = series.chart,\r\n legendItem = series.legendItem,\r\n showOrHide,\r\n ignoreHiddenSeries = chart.options.chart.ignoreHiddenSeries,\r\n oldVisibility = series.visible;\r\n\r\n // if called without an argument, toggle visibility\r\n series.visible = vis = series.userOptions.visible =\r\n vis === UNDEFINED ? !oldVisibility : vis;\r\n showOrHide = vis ? \"show\" : \"hide\";\r\n\r\n // show or hide elements\r\n each([\"group\", \"dataLabelsGroup\", \"markerGroup\", \"tracker\"], function(\r\n key\r\n ) {\r\n if (series[key]) {\r\n series[key][showOrHide]();\r\n }\r\n });\r\n\r\n // hide tooltip (#1361)\r\n if (chart.hoverSeries === series) {\r\n series.onMouseOut();\r\n }\r\n\r\n if (legendItem) {\r\n chart.legend.colorizeItem(series, vis);\r\n }\r\n\r\n // rescale or adapt to resized chart\r\n series.isDirty = true;\r\n // in a stack, all other series are affected\r\n if (series.options.stacking) {\r\n each(chart.series, function(otherSeries) {\r\n if (otherSeries.options.stacking && otherSeries.visible) {\r\n otherSeries.isDirty = true;\r\n }\r\n });\r\n }\r\n\r\n // show or hide linked series\r\n each(series.linkedSeries, function(otherSeries) {\r\n otherSeries.setVisible(vis, false);\r\n });\r\n\r\n if (ignoreHiddenSeries) {\r\n chart.isDirtyBox = true;\r\n }\r\n if (redraw !== false) {\r\n chart.redraw();\r\n }\r\n\r\n fireEvent(series, showOrHide);\r\n },\r\n\r\n /**\r\n * Show the graph\r\n */\r\n show: function() {\r\n this.setVisible(true);\r\n },\r\n\r\n /**\r\n * Hide the graph\r\n */\r\n hide: function() {\r\n this.setVisible(false);\r\n },\r\n\r\n /**\r\n * Set the selected state of the graph\r\n *\r\n * @param selected {Boolean} True to select the series, false to unselect. If\r\n * UNDEFINED, the selection state is toggled.\r\n */\r\n select: function(selected) {\r\n var series = this;\r\n // if called without an argument, toggle\r\n series.selected = selected =\r\n selected === UNDEFINED ? !series.selected : selected;\r\n\r\n if (series.checkbox) {\r\n series.checkbox.checked = selected;\r\n }\r\n\r\n fireEvent(series, selected ? \"select\" : \"unselect\");\r\n },\r\n\r\n /**\r\n * Draw the tracker object that sits above all data labels and markers to\r\n * track mouse events on the graph or points. For the line type charts\r\n * the tracker uses the same graphPath, but with a greater stroke width\r\n * for better control.\r\n */\r\n drawTracker: function() {\r\n var series = this,\r\n options = series.options,\r\n trackByArea = options.trackByArea,\r\n trackerPath = [].concat(\r\n trackByArea ? series.areaPath : series.graphPath\r\n ),\r\n trackerPathLength = trackerPath.length,\r\n chart = series.chart,\r\n pointer = chart.pointer,\r\n renderer = chart.renderer,\r\n snap = chart.options.tooltip.snap,\r\n tracker = series.tracker,\r\n cursor = options.cursor,\r\n css = cursor && { cursor: cursor },\r\n singlePoints = series.singlePoints,\r\n singlePoint,\r\n i,\r\n onMouseOver = function() {\r\n if (chart.hoverSeries !== series) {\r\n series.onMouseOver();\r\n }\r\n };\r\n\r\n // Extend end points. A better way would be to use round linecaps,\r\n // but those are not clickable in VML.\r\n if (trackerPathLength && !trackByArea) {\r\n i = trackerPathLength + 1;\r\n while (i--) {\r\n if (trackerPath[i] === M) {\r\n // extend left side\r\n trackerPath.splice(\r\n i + 1,\r\n 0,\r\n trackerPath[i + 1] - snap,\r\n trackerPath[i + 2],\r\n L\r\n );\r\n }\r\n if ((i && trackerPath[i] === M) || i === trackerPathLength) {\r\n // extend right side\r\n trackerPath.splice(\r\n i,\r\n 0,\r\n L,\r\n trackerPath[i - 2] + snap,\r\n trackerPath[i - 1]\r\n );\r\n }\r\n }\r\n }\r\n\r\n // handle single points\r\n for (i = 0; i < singlePoints.length; i++) {\r\n singlePoint = singlePoints[i];\r\n trackerPath.push(\r\n M,\r\n singlePoint.plotX - snap,\r\n singlePoint.plotY,\r\n L,\r\n singlePoint.plotX + snap,\r\n singlePoint.plotY\r\n );\r\n }\r\n\r\n // draw the tracker\r\n if (tracker) {\r\n tracker.attr({ d: trackerPath });\r\n }\r\n else {\r\n // create\r\n\r\n series.tracker = renderer\r\n .path(trackerPath)\r\n .attr({\r\n \"stroke-linejoin\": \"round\", // #1225\r\n visibility: series.visible ? VISIBLE : HIDDEN,\r\n stroke: TRACKER_FILL,\r\n fill: trackByArea ? TRACKER_FILL : NONE,\r\n \"stroke-width\": options.lineWidth + (trackByArea ? 0 : 2 * snap),\r\n zIndex: 2\r\n })\r\n .add(series.group);\r\n\r\n // The tracker is added to the series group, which is clipped, but is covered\r\n // by the marker group. So the marker group also needs to capture events.\r\n each([series.tracker, series.markerGroup], function(tracker) {\r\n tracker\r\n .addClass(PREFIX + \"tracker\")\r\n .on(\"mouseover\", onMouseOver)\r\n .on(\"mouseout\", function(e) {\r\n pointer.onTrackerMouseOut(e);\r\n })\r\n .css(css);\r\n\r\n if (hasTouch) {\r\n tracker.on(\"touchstart\", onMouseOver);\r\n }\r\n });\r\n }\r\n }\r\n }; // end Series prototype\r\n\r\n /**\r\n * LineSeries object\r\n */\r\n var LineSeries = extendClass(Series);\r\n seriesTypes.line = LineSeries;\r\n\r\n /**\r\n * Set the default options for area\r\n */\r\n defaultPlotOptions.area = merge(defaultSeriesOptions, {\r\n threshold: 0\r\n // trackByArea: false,\r\n // lineColor: null, // overrides color, but lets fillColor be unaltered\r\n // fillOpacity: 0.75,\r\n // fillColor: null\r\n });\r\n\r\n /**\r\n * AreaSeries object\r\n */\r\n var AreaSeries = extendClass(Series, {\r\n type: \"area\",\r\n\r\n /**\r\n * For stacks, don't split segments on null values. Instead, draw null values with\r\n * no marker. Also insert dummy points for any X position that exists in other series\r\n * in the stack.\r\n */\r\n\r\n getSegments: function() {\r\n var segments = [],\r\n segment = [],\r\n keys = [],\r\n xAxis = this.xAxis,\r\n yAxis = this.yAxis,\r\n stack = yAxis.stacks[this.stackKey],\r\n pointMap = {},\r\n plotX,\r\n plotY,\r\n points = this.points,\r\n connectNulls = this.options.connectNulls,\r\n val,\r\n i,\r\n x;\r\n\r\n if (this.options.stacking && !this.cropped) {\r\n // cropped causes artefacts in Stock, and perf issue\r\n // Create a map where we can quickly look up the points by their X value.\r\n for (i = 0; i < points.length; i++) {\r\n pointMap[points[i].x] = points[i];\r\n }\r\n\r\n // Sort the keys (#1651)\r\n for (x in stack) {\r\n if (stack[x].total !== null) {\r\n // nulled after switching between grouping and not (#1651, #2336)\r\n keys.push(+x);\r\n }\r\n }\r\n keys.sort(function(a, b) {\r\n return a - b;\r\n });\r\n\r\n each(keys, function(x) {\r\n if (connectNulls && (!pointMap[x] || pointMap[x].y === null)) {\r\n // #1836\r\n return;\r\n\r\n // The point exists, push it to the segment\r\n }\r\n else if (pointMap[x]) {\r\n segment.push(pointMap[x]);\r\n\r\n // There is no point for this X value in this series, so we\r\n // insert a dummy point in order for the areas to be drawn\r\n // correctly.\r\n }\r\n else {\r\n plotX = xAxis.translate(x);\r\n val = stack[x].percent\r\n ? stack[x].total\r\n ? (stack[x].cum * 100) / stack[x].total\r\n : 0\r\n : stack[x].cum; // #1991\r\n plotY = yAxis.toPixels(val, true);\r\n segment.push({\r\n y: null,\r\n plotX: plotX,\r\n clientX: plotX,\r\n plotY: plotY,\r\n yBottom: plotY,\r\n onMouseOver: noop\r\n });\r\n }\r\n });\r\n\r\n if (segment.length) {\r\n segments.push(segment);\r\n }\r\n }\r\n else {\r\n Series.prototype.getSegments.call(this);\r\n segments = this.segments;\r\n }\r\n\r\n this.segments = segments;\r\n },\r\n\r\n /**\r\n * Extend the base Series getSegmentPath method by adding the path for the area.\r\n * This path is pushed to the series.areaPath property.\r\n */\r\n getSegmentPath: function(segment) {\r\n var segmentPath = Series.prototype.getSegmentPath.call(this, segment), // call base method\r\n areaSegmentPath = [].concat(segmentPath), // work on a copy for the area path\r\n i,\r\n options = this.options,\r\n segLength = segmentPath.length,\r\n translatedThreshold = this.yAxis.getThreshold(options.threshold), // #2181\r\n yBottom;\r\n\r\n if (segLength === 3) {\r\n // for animation from 1 to two points\r\n areaSegmentPath.push(L, segmentPath[1], segmentPath[2]);\r\n }\r\n if (options.stacking && !this.closedStacks) {\r\n // Follow stack back. Todo: implement areaspline. A general solution could be to\r\n // reverse the entire graphPath of the previous series, though may be hard with\r\n // splines and with series with different extremes\r\n for (i = segment.length - 1; i >= 0; i--) {\r\n yBottom = pick(segment[i].yBottom, translatedThreshold);\r\n\r\n // step line?\r\n if (i < segment.length - 1 && options.step) {\r\n areaSegmentPath.push(segment[i + 1].plotX, yBottom);\r\n }\r\n\r\n areaSegmentPath.push(segment[i].plotX, yBottom);\r\n }\r\n }\r\n else {\r\n // follow zero line back\r\n this.closeSegment(areaSegmentPath, segment, translatedThreshold);\r\n }\r\n this.areaPath = this.areaPath.concat(areaSegmentPath);\r\n return segmentPath;\r\n },\r\n\r\n /**\r\n * Extendable method to close the segment path of an area. This is overridden in polar\r\n * charts.\r\n */\r\n closeSegment: function(path, segment, translatedThreshold) {\r\n path.push(\r\n L,\r\n segment[segment.length - 1].plotX,\r\n translatedThreshold,\r\n L,\r\n segment[0].plotX,\r\n translatedThreshold\r\n );\r\n },\r\n\r\n /**\r\n * Draw the graph and the underlying area. This method calls the Series base\r\n * function and adds the area. The areaPath is calculated in the getSegmentPath\r\n * method called from Series.prototype.drawGraph.\r\n */\r\n drawGraph: function() {\r\n // Define or reset areaPath\r\n this.areaPath = [];\r\n\r\n // Call the base method\r\n Series.prototype.drawGraph.apply(this);\r\n\r\n // Define local variables\r\n var series = this,\r\n areaPath = this.areaPath,\r\n options = this.options,\r\n negativeColor = options.negativeColor,\r\n negativeFillColor = options.negativeFillColor,\r\n props = [[\"area\", this.color, options.fillColor]]; // area name, main color, fill color\r\n\r\n if (negativeColor || negativeFillColor) {\r\n props.push([\"areaNeg\", negativeColor, negativeFillColor]);\r\n }\r\n\r\n each(props, function(prop) {\r\n var areaKey = prop[0],\r\n area = series[areaKey];\r\n\r\n // Create or update the area\r\n if (area) {\r\n // update\r\n area.animate({ d: areaPath });\r\n }\r\n else {\r\n // create\r\n series[areaKey] = series.chart.renderer\r\n .path(areaPath)\r\n .attr({\r\n fill: pick(\r\n prop[2],\r\n Color(prop[1])\r\n .setOpacity(pick(options.fillOpacity, 0.75))\r\n .get()\r\n ),\r\n zIndex: 0 // #1069\r\n })\r\n .add(series.group);\r\n }\r\n });\r\n },\r\n\r\n /**\r\n * Get the series' symbol in the legend\r\n *\r\n * @param {Object} legend The legend object\r\n * @param {Object} item The series (this) or point\r\n */\r\n drawLegendSymbol: function(legend, item) {\r\n item.legendSymbol = this.chart.renderer\r\n .rect(0, legend.baseline - 11, legend.options.symbolWidth, 12, 2)\r\n .attr({\r\n zIndex: 3\r\n })\r\n .add(item.legendGroup);\r\n }\r\n });\r\n\r\n seriesTypes.area = AreaSeries;\r\n /**\r\n * Set the default options for spline\r\n */\r\n defaultPlotOptions.spline = merge(defaultSeriesOptions);\r\n\r\n /**\r\n * SplineSeries object\r\n */\r\n var SplineSeries = extendClass(Series, {\r\n type: \"spline\",\r\n\r\n /**\r\n * Get the spline segment from a given point's previous neighbour to the given point\r\n */\r\n getPointSpline: function(segment, point, i) {\r\n var smoothing = 1.5, // 1 means control points midway between points, 2 means 1/3 from the point, 3 is 1/4 etc\r\n denom = smoothing + 1,\r\n plotX = point.plotX,\r\n plotY = point.plotY,\r\n lastPoint = segment[i - 1],\r\n nextPoint = segment[i + 1],\r\n leftContX,\r\n leftContY,\r\n rightContX,\r\n rightContY,\r\n ret;\r\n\r\n // find control points\r\n if (lastPoint && nextPoint) {\r\n var lastX = lastPoint.plotX,\r\n lastY = lastPoint.plotY,\r\n nextX = nextPoint.plotX,\r\n nextY = nextPoint.plotY,\r\n correction;\r\n\r\n leftContX = (smoothing * plotX + lastX) / denom;\r\n leftContY = (smoothing * plotY + lastY) / denom;\r\n rightContX = (smoothing * plotX + nextX) / denom;\r\n rightContY = (smoothing * plotY + nextY) / denom;\r\n\r\n // have the two control points make a straight line through main point\r\n correction =\r\n ((rightContY - leftContY) * (rightContX - plotX)) /\r\n (rightContX - leftContX) +\r\n plotY -\r\n rightContY;\r\n\r\n leftContY += correction;\r\n rightContY += correction;\r\n\r\n // to prevent false extremes, check that control points are between\r\n // neighbouring points' y values\r\n if (leftContY > lastY && leftContY > plotY) {\r\n leftContY = mathMax(lastY, plotY);\r\n rightContY = 2 * plotY - leftContY; // mirror of left control point\r\n }\r\n else if (leftContY < lastY && leftContY < plotY) {\r\n leftContY = mathMin(lastY, plotY);\r\n rightContY = 2 * plotY - leftContY;\r\n }\r\n if (rightContY > nextY && rightContY > plotY) {\r\n rightContY = mathMax(nextY, plotY);\r\n leftContY = 2 * plotY - rightContY;\r\n }\r\n else if (rightContY < nextY && rightContY < plotY) {\r\n rightContY = mathMin(nextY, plotY);\r\n leftContY = 2 * plotY - rightContY;\r\n }\r\n\r\n // record for drawing in next point\r\n point.rightContX = rightContX;\r\n point.rightContY = rightContY;\r\n }\r\n\r\n // Visualize control points for debugging\r\n /*\r\n\t\tif (leftContX) {\r\n\t\t\tthis.chart.renderer.circle(leftContX + this.chart.plotLeft, leftContY + this.chart.plotTop, 2)\r\n\t\t\t\t.attr({\r\n\t\t\t\t\tstroke: 'red',\r\n\t\t\t\t\t'stroke-width': 1,\r\n\t\t\t\t\tfill: 'none'\r\n\t\t\t\t})\r\n\t\t\t\t.add();\r\n\t\t\tthis.chart.renderer.path(['M', leftContX + this.chart.plotLeft, leftContY + this.chart.plotTop,\r\n\t\t\t\t'L', plotX + this.chart.plotLeft, plotY + this.chart.plotTop])\r\n\t\t\t\t.attr({\r\n\t\t\t\t\tstroke: 'red',\r\n\t\t\t\t\t'stroke-width': 1\r\n\t\t\t\t})\r\n\t\t\t\t.add();\r\n\t\t\tthis.chart.renderer.circle(rightContX + this.chart.plotLeft, rightContY + this.chart.plotTop, 2)\r\n\t\t\t\t.attr({\r\n\t\t\t\t\tstroke: 'green',\r\n\t\t\t\t\t'stroke-width': 1,\r\n\t\t\t\t\tfill: 'none'\r\n\t\t\t\t})\r\n\t\t\t\t.add();\r\n\t\t\tthis.chart.renderer.path(['M', rightContX + this.chart.plotLeft, rightContY + this.chart.plotTop,\r\n\t\t\t\t'L', plotX + this.chart.plotLeft, plotY + this.chart.plotTop])\r\n\t\t\t\t.attr({\r\n\t\t\t\t\tstroke: 'green',\r\n\t\t\t\t\t'stroke-width': 1\r\n\t\t\t\t})\r\n\t\t\t\t.add();\r\n\t\t}\r\n\t\t*/\r\n\r\n // moveTo or lineTo\r\n if (!i) {\r\n ret = [M, plotX, plotY];\r\n }\r\n else {\r\n // curve from last point to this\r\n ret = [\r\n \"C\",\r\n lastPoint.rightContX || lastPoint.plotX,\r\n lastPoint.rightContY || lastPoint.plotY,\r\n leftContX || plotX,\r\n leftContY || plotY,\r\n plotX,\r\n plotY\r\n ];\r\n lastPoint.rightContX = lastPoint.rightContY = null; // reset for updating series later\r\n }\r\n return ret;\r\n }\r\n });\r\n seriesTypes.spline = SplineSeries;\r\n\r\n /**\r\n * Set the default options for areaspline\r\n */\r\n defaultPlotOptions.areaspline = merge(defaultPlotOptions.area);\r\n\r\n /**\r\n * AreaSplineSeries object\r\n */\r\n var areaProto = AreaSeries.prototype,\r\n AreaSplineSeries = extendClass(SplineSeries, {\r\n type: \"areaspline\",\r\n closedStacks: true, // instead of following the previous graph back, follow the threshold back\r\n\r\n // Mix in methods from the area series\r\n getSegmentPath: areaProto.getSegmentPath,\r\n closeSegment: areaProto.closeSegment,\r\n drawGraph: areaProto.drawGraph,\r\n drawLegendSymbol: areaProto.drawLegendSymbol\r\n });\r\n seriesTypes.areaspline = AreaSplineSeries;\r\n\r\n /**\r\n * Set the default options for column\r\n */\r\n defaultPlotOptions.column = merge(defaultSeriesOptions, {\r\n borderColor: \"#FFFFFF\",\r\n borderWidth: 1,\r\n borderRadius: 0,\r\n //colorByPoint: undefined,\r\n groupPadding: 0.2,\r\n //grouping: true,\r\n marker: null, // point options are specified in the base options\r\n pointPadding: 0.1,\r\n //pointWidth: null,\r\n minPointLength: 0,\r\n cropThreshold: 50, // when there are more points, they will not animate out of the chart on xAxis.setExtremes\r\n pointRange: null, // null means auto, meaning 1 in a categorized axis and least distance between points if not categories\r\n states: {\r\n hover: {\r\n brightness: 0.1,\r\n shadow: false\r\n },\r\n select: {\r\n color: \"#C0C0C0\",\r\n borderColor: \"#000000\",\r\n shadow: false\r\n }\r\n },\r\n dataLabels: {\r\n align: null, // auto\r\n verticalAlign: null, // auto\r\n y: null\r\n },\r\n stickyTracking: false,\r\n threshold: 0\r\n });\r\n\r\n /**\r\n * ColumnSeries object\r\n */\r\n var ColumnSeries = extendClass(Series, {\r\n type: \"column\",\r\n pointAttrToOptions: {\r\n // mapping between SVG attributes and the corresponding options\r\n stroke: \"borderColor\",\r\n \"stroke-width\": \"borderWidth\",\r\n fill: \"color\",\r\n r: \"borderRadius\"\r\n },\r\n cropShoulder: 0,\r\n trackerGroups: [\"group\", \"dataLabelsGroup\"],\r\n negStacks: true, // use separate negative stacks, unlike area stacks where a negative\r\n // point is substracted from previous (#1910)\r\n\r\n /**\r\n * Initialize the series\r\n */\r\n init: function() {\r\n Series.prototype.init.apply(this, arguments);\r\n\r\n var series = this,\r\n chart = series.chart;\r\n\r\n // if the series is added dynamically, force redraw of other\r\n // series affected by a new column\r\n if (chart.hasRendered) {\r\n each(chart.series, function(otherSeries) {\r\n if (otherSeries.type === series.type) {\r\n otherSeries.isDirty = true;\r\n }\r\n });\r\n }\r\n },\r\n\r\n /**\r\n * Return the width and x offset of the columns adjusted for grouping, groupPadding, pointPadding,\r\n * pointWidth etc.\r\n */\r\n getColumnMetrics: function() {\r\n var series = this,\r\n options = series.options,\r\n xAxis = series.xAxis,\r\n yAxis = series.yAxis,\r\n reversedXAxis = xAxis.reversed,\r\n stackKey,\r\n stackGroups = {},\r\n columnIndex,\r\n columnCount = 0;\r\n\r\n // Get the total number of column type series.\r\n // This is called on every series. Consider moving this logic to a\r\n // chart.orderStacks() function and call it on init, addSeries and removeSeries\r\n if (options.grouping === false) {\r\n columnCount = 1;\r\n }\r\n else {\r\n each(series.chart.series, function(otherSeries) {\r\n var otherOptions = otherSeries.options,\r\n otherYAxis = otherSeries.yAxis;\r\n if (\r\n otherSeries.type === series.type &&\r\n otherSeries.visible &&\r\n yAxis.len === otherYAxis.len &&\r\n yAxis.pos === otherYAxis.pos\r\n ) {\r\n // #642, #2086\r\n if (otherOptions.stacking) {\r\n stackKey = otherSeries.stackKey;\r\n if (stackGroups[stackKey] === UNDEFINED) {\r\n stackGroups[stackKey] = columnCount++;\r\n }\r\n columnIndex = stackGroups[stackKey];\r\n }\r\n else if (otherOptions.grouping !== false) {\r\n // #1162\r\n columnIndex = columnCount++;\r\n }\r\n otherSeries.columnIndex = columnIndex;\r\n }\r\n });\r\n }\r\n\r\n var categoryWidth = mathMin(\r\n mathAbs(xAxis.transA) *\r\n (xAxis.ordinalSlope ||\r\n options.pointRange ||\r\n xAxis.closestPointRange ||\r\n 1),\r\n xAxis.len // #1535\r\n ),\r\n groupPadding = categoryWidth * options.groupPadding,\r\n groupWidth = categoryWidth - 2 * groupPadding,\r\n pointOffsetWidth = groupWidth / columnCount,\r\n optionPointWidth = options.pointWidth,\r\n pointPadding = defined(optionPointWidth)\r\n ? (pointOffsetWidth - optionPointWidth) / 2\r\n : pointOffsetWidth * options.pointPadding,\r\n pointWidth = pick(\r\n optionPointWidth,\r\n pointOffsetWidth - 2 * pointPadding\r\n ), // exact point width, used in polar charts\r\n colIndex =\r\n (reversedXAxis\r\n ? columnCount - (series.columnIndex || 0) // #1251\r\n : series.columnIndex) || 0,\r\n pointXOffset =\r\n pointPadding +\r\n (groupPadding + colIndex * pointOffsetWidth - categoryWidth / 2) *\r\n (reversedXAxis ? -1 : 1);\r\n\r\n // Save it for reading in linked series (Error bars particularly)\r\n return (series.columnMetrics = {\r\n width: pointWidth,\r\n offset: pointXOffset\r\n });\r\n },\r\n\r\n /**\r\n * Translate each point to the plot area coordinate system and find shape positions\r\n */\r\n translate: function() {\r\n var series = this,\r\n chart = series.chart,\r\n options = series.options,\r\n borderWidth = options.borderWidth,\r\n yAxis = series.yAxis,\r\n threshold = options.threshold,\r\n translatedThreshold = (series.translatedThreshold = yAxis.getThreshold(\r\n threshold\r\n )),\r\n minPointLength = pick(options.minPointLength, 5),\r\n metrics = series.getColumnMetrics(),\r\n pointWidth = metrics.width,\r\n seriesBarW = (series.barW = mathCeil(\r\n mathMax(pointWidth, 1 + 2 * borderWidth)\r\n )), // rounded and postprocessed for border width\r\n pointXOffset = (series.pointXOffset = metrics.offset),\r\n xCrisp = -(borderWidth % 2 ? 0.5 : 0),\r\n yCrisp = borderWidth % 2 ? 0.5 : 1;\r\n\r\n if (chart.renderer.isVML && chart.inverted) {\r\n yCrisp += 1;\r\n }\r\n\r\n Series.prototype.translate.apply(series);\r\n\r\n // record the new values\r\n each(series.points, function(point) {\r\n var yBottom = pick(point.yBottom, translatedThreshold),\r\n plotY = mathMin(\r\n mathMax(-999 - yBottom, point.plotY),\r\n yAxis.len + 999 + yBottom\r\n ), // Don't draw too far outside plot area (#1303, #2241)\r\n barX = point.plotX + pointXOffset,\r\n barW = seriesBarW,\r\n barY = mathMin(plotY, yBottom),\r\n right,\r\n bottom,\r\n fromTop,\r\n fromLeft,\r\n barH = mathMax(plotY, yBottom) - barY;\r\n\r\n // Handle options.minPointLength\r\n if (mathAbs(barH) < minPointLength) {\r\n if (minPointLength) {\r\n barH = minPointLength;\r\n barY = mathRound(\r\n mathAbs(barY - translatedThreshold) > minPointLength // stacked\r\n ? yBottom - minPointLength // keep position\r\n : translatedThreshold -\r\n (yAxis.translate(point.y, 0, 1, 0, 1) <= translatedThreshold\r\n ? minPointLength\r\n : 0)\r\n ); // use exact yAxis.translation (#1485)\r\n }\r\n }\r\n\r\n // Cache for access in polar\r\n point.barX = barX;\r\n point.pointWidth = pointWidth;\r\n\r\n // Round off to obtain crisp edges\r\n fromLeft = mathAbs(barX) < 0.5;\r\n right = mathRound(barX + barW) + xCrisp;\r\n barX = mathRound(barX) + xCrisp;\r\n barW = right - barX;\r\n\r\n fromTop = mathAbs(barY) < 0.5;\r\n bottom = mathRound(barY + barH) + yCrisp;\r\n barY = mathRound(barY) + yCrisp;\r\n barH = bottom - barY;\r\n\r\n // Top and left edges are exceptions\r\n if (fromLeft) {\r\n barX += 1;\r\n barW -= 1;\r\n }\r\n if (fromTop) {\r\n barY -= 1;\r\n barH += 1;\r\n }\r\n\r\n // Register shape type and arguments to be used in drawPoints\r\n point.shapeType = \"rect\";\r\n point.shapeArgs = {\r\n x: barX,\r\n y: barY,\r\n width: barW,\r\n height: barH\r\n };\r\n });\r\n },\r\n\r\n getSymbol: noop,\r\n\r\n /**\r\n * Use a solid rectangle like the area series types\r\n */\r\n drawLegendSymbol: AreaSeries.prototype.drawLegendSymbol,\r\n\r\n /**\r\n * Columns have no graph\r\n */\r\n drawGraph: noop,\r\n\r\n /**\r\n * Draw the columns. For bars, the series.group is rotated, so the same coordinates\r\n * apply for columns and bars. This method is inherited by scatter series.\r\n *\r\n */\r\n drawPoints: function() {\r\n var series = this,\r\n options = series.options,\r\n renderer = series.chart.renderer,\r\n shapeArgs;\r\n\r\n // draw the columns\r\n each(series.points, function(point) {\r\n var plotY = point.plotY,\r\n graphic = point.graphic;\r\n\r\n if (plotY !== UNDEFINED && !isNaN(plotY) && point.y !== null) {\r\n shapeArgs = point.shapeArgs;\r\n\r\n if (graphic) {\r\n // update\r\n stop(graphic);\r\n graphic.animate(merge(shapeArgs));\r\n }\r\n else {\r\n point.graphic = graphic = renderer[point.shapeType](shapeArgs)\r\n .attr(\r\n point.pointAttr[point.selected ? SELECT_STATE : NORMAL_STATE]\r\n )\r\n .add(series.group)\r\n .shadow(\r\n options.shadow,\r\n null,\r\n options.stacking && !options.borderRadius\r\n );\r\n }\r\n }\r\n else if (graphic) {\r\n point.graphic = graphic.destroy(); // #1269\r\n }\r\n });\r\n },\r\n\r\n /**\r\n * Add tracking event listener to the series group, so the point graphics\r\n * themselves act as trackers\r\n */\r\n drawTracker: function() {\r\n var series = this,\r\n chart = series.chart,\r\n pointer = chart.pointer,\r\n cursor = series.options.cursor,\r\n css = cursor && { cursor: cursor },\r\n onMouseOver = function(e) {\r\n var target = e.target,\r\n point;\r\n\r\n if (chart.hoverSeries !== series) {\r\n series.onMouseOver();\r\n }\r\n while (target && !point) {\r\n point = target.point;\r\n target = target.parentNode;\r\n }\r\n if (point !== UNDEFINED && point !== chart.hoverPoint) {\r\n // undefined on graph in scatterchart\r\n point.onMouseOver(e);\r\n }\r\n };\r\n\r\n // Add reference to the point\r\n each(series.points, function(point) {\r\n if (point.graphic) {\r\n point.graphic.element.point = point;\r\n }\r\n if (point.dataLabel) {\r\n point.dataLabel.element.point = point;\r\n }\r\n });\r\n\r\n // Add the event listeners, we need to do this only once\r\n if (!series._hasTracking) {\r\n each(series.trackerGroups, function(key) {\r\n if (series[key]) {\r\n // we don't always have dataLabelsGroup\r\n series[key]\r\n .addClass(PREFIX + \"tracker\")\r\n .on(\"mouseover\", onMouseOver)\r\n .on(\"mouseout\", function(e) {\r\n pointer.onTrackerMouseOut(e);\r\n })\r\n .css(css);\r\n if (hasTouch) {\r\n series[key].on(\"touchstart\", onMouseOver);\r\n }\r\n }\r\n });\r\n series._hasTracking = true;\r\n }\r\n },\r\n\r\n /**\r\n * Override the basic data label alignment by adjusting for the position of the column\r\n */\r\n alignDataLabel: function(point, dataLabel, options, alignTo, isNew) {\r\n var chart = this.chart,\r\n inverted = chart.inverted,\r\n dlBox = point.dlBox || point.shapeArgs, // data label box for alignment\r\n below =\r\n point.below ||\r\n point.plotY > pick(this.translatedThreshold, chart.plotSizeY),\r\n inside = pick(options.inside, !!this.options.stacking); // draw it inside the box?\r\n\r\n // Align to the column itself, or the top of it\r\n if (dlBox) {\r\n // Area range uses this method but not alignTo\r\n alignTo = merge(dlBox);\r\n if (inverted) {\r\n alignTo = {\r\n x: chart.plotWidth - alignTo.y - alignTo.height,\r\n y: chart.plotHeight - alignTo.x - alignTo.width,\r\n width: alignTo.height,\r\n height: alignTo.width\r\n };\r\n }\r\n\r\n // Compute the alignment box\r\n if (!inside) {\r\n if (inverted) {\r\n alignTo.x += below ? 0 : alignTo.width;\r\n alignTo.width = 0;\r\n }\r\n else {\r\n alignTo.y += below ? alignTo.height : 0;\r\n alignTo.height = 0;\r\n }\r\n }\r\n }\r\n\r\n // When alignment is undefined (typically columns and bars), display the individual\r\n // point below or above the point depending on the threshold\r\n options.align = pick(\r\n options.align,\r\n !inverted || inside ? \"center\" : below ? \"right\" : \"left\"\r\n );\r\n options.verticalAlign = pick(\r\n options.verticalAlign,\r\n inverted || inside ? \"middle\" : below ? \"top\" : \"bottom\"\r\n );\r\n\r\n // Call the parent method\r\n Series.prototype.alignDataLabel.call(\r\n this,\r\n point,\r\n dataLabel,\r\n options,\r\n alignTo,\r\n isNew\r\n );\r\n },\r\n\r\n /**\r\n * Animate the column heights one by one from zero\r\n * @param {Boolean} init Whether to initialize the animation or run it\r\n */\r\n animate: function(init) {\r\n var series = this,\r\n yAxis = this.yAxis,\r\n options = series.options,\r\n inverted = this.chart.inverted,\r\n attr = {},\r\n translatedThreshold;\r\n\r\n if (hasSVG) {\r\n // VML is too slow anyway\r\n if (init) {\r\n attr.scaleY = 0.001;\r\n translatedThreshold = mathMin(\r\n yAxis.pos + yAxis.len,\r\n mathMax(yAxis.pos, yAxis.toPixels(options.threshold))\r\n );\r\n if (inverted) {\r\n attr.translateX = translatedThreshold - yAxis.len;\r\n }\r\n else {\r\n attr.translateY = translatedThreshold;\r\n }\r\n series.group.attr(attr);\r\n }\r\n else {\r\n // run the animation\r\n\r\n attr.scaleY = 1;\r\n attr[inverted ? \"translateX\" : \"translateY\"] = yAxis.pos;\r\n series.group.animate(attr, series.options.animation);\r\n\r\n // delete this function to allow it only once\r\n series.animate = null;\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Remove this series from the chart\r\n */\r\n remove: function() {\r\n var series = this,\r\n chart = series.chart;\r\n\r\n // column and bar series affects other series of the same type\r\n // as they are either stacked or grouped\r\n if (chart.hasRendered) {\r\n each(chart.series, function(otherSeries) {\r\n if (otherSeries.type === series.type) {\r\n otherSeries.isDirty = true;\r\n }\r\n });\r\n }\r\n\r\n Series.prototype.remove.apply(series, arguments);\r\n }\r\n });\r\n seriesTypes.column = ColumnSeries;\r\n /**\r\n * Set the default options for bar\r\n */\r\n defaultPlotOptions.bar = merge(defaultPlotOptions.column);\r\n /**\r\n * The Bar series class\r\n */\r\n var BarSeries = extendClass(ColumnSeries, {\r\n type: \"bar\",\r\n inverted: true\r\n });\r\n seriesTypes.bar = BarSeries;\r\n\r\n /**\r\n * Set the default options for scatter\r\n */\r\n defaultPlotOptions.scatter = merge(defaultSeriesOptions, {\r\n lineWidth: 0,\r\n tooltip: {\r\n headerFormat:\r\n '{series.name}
',\r\n pointFormat: \"x: {point.x}
y: {point.y}
\",\r\n followPointer: true\r\n },\r\n stickyTracking: false\r\n });\r\n\r\n /**\r\n * The scatter series class\r\n */\r\n var ScatterSeries = extendClass(Series, {\r\n type: \"scatter\",\r\n sorted: false,\r\n requireSorting: false,\r\n noSharedTooltip: true,\r\n trackerGroups: [\"markerGroup\"],\r\n takeOrdinalPosition: false, // #2342\r\n drawTracker: ColumnSeries.prototype.drawTracker,\r\n\r\n setTooltipPoints: noop\r\n });\r\n seriesTypes.scatter = ScatterSeries;\r\n\r\n /**\r\n * Set the default options for pie\r\n */\r\n defaultPlotOptions.pie = merge(defaultSeriesOptions, {\r\n borderColor: \"#FFFFFF\",\r\n borderWidth: 1,\r\n center: [null, null],\r\n clip: false,\r\n colorByPoint: true, // always true for pies\r\n dataLabels: {\r\n // align: null,\r\n // connectorWidth: 1,\r\n // connectorColor: point.color,\r\n // connectorPadding: 5,\r\n distance: 30,\r\n enabled: true,\r\n formatter: function() {\r\n return this.point.name;\r\n }\r\n // softConnector: true,\r\n //y: 0\r\n },\r\n ignoreHiddenPoint: true,\r\n //innerSize: 0,\r\n legendType: \"point\",\r\n marker: null, // point options are specified in the base options\r\n size: null,\r\n showInLegend: false,\r\n slicedOffset: 10,\r\n states: {\r\n hover: {\r\n brightness: 0.1,\r\n shadow: false\r\n }\r\n },\r\n stickyTracking: false,\r\n tooltip: {\r\n followPointer: true\r\n }\r\n });\r\n\r\n /**\r\n * Extended point object for pies\r\n */\r\n var PiePoint = extendClass(Point, {\r\n /**\r\n * Initiate the pie slice\r\n */\r\n init: function() {\r\n Point.prototype.init.apply(this, arguments);\r\n\r\n var point = this,\r\n toggleSlice;\r\n\r\n // Disallow negative values (#1530)\r\n if (point.y < 0) {\r\n point.y = null;\r\n }\r\n\r\n //visible: options.visible !== false,\r\n extend(point, {\r\n visible: point.visible !== false,\r\n name: pick(point.name, \"Slice\")\r\n });\r\n\r\n // add event listener for select\r\n toggleSlice = function(e) {\r\n point.slice(e.type === \"select\");\r\n };\r\n addEvent(point, \"select\", toggleSlice);\r\n addEvent(point, \"unselect\", toggleSlice);\r\n\r\n return point;\r\n },\r\n\r\n /**\r\n * Toggle the visibility of the pie slice\r\n * @param {Boolean} vis Whether to show the slice or not. If undefined, the\r\n * visibility is toggled\r\n */\r\n setVisible: function(vis) {\r\n var point = this,\r\n series = point.series,\r\n chart = series.chart,\r\n method;\r\n\r\n // if called without an argument, toggle visibility\r\n point.visible = point.options.visible = vis =\r\n vis === UNDEFINED ? !point.visible : vis;\r\n series.options.data[inArray(point, series.data)] = point.options; // update userOptions.data\r\n\r\n method = vis ? \"show\" : \"hide\";\r\n\r\n // Show and hide associated elements\r\n each([\"graphic\", \"dataLabel\", \"connector\", \"shadowGroup\"], function(key) {\r\n if (point[key]) {\r\n point[key][method]();\r\n }\r\n });\r\n\r\n if (point.legendItem) {\r\n chart.legend.colorizeItem(point, vis);\r\n }\r\n\r\n // Handle ignore hidden slices\r\n if (!series.isDirty && series.options.ignoreHiddenPoint) {\r\n series.isDirty = true;\r\n chart.redraw();\r\n }\r\n },\r\n\r\n /**\r\n * Set or toggle whether the slice is cut out from the pie\r\n * @param {Boolean} sliced When undefined, the slice state is toggled\r\n * @param {Boolean} redraw Whether to redraw the chart. True by default.\r\n */\r\n slice: function(sliced, redraw, animation) {\r\n var point = this,\r\n series = point.series,\r\n chart = series.chart,\r\n translation;\r\n\r\n setAnimation(animation, chart);\r\n\r\n // redraw is true by default\r\n redraw = pick(redraw, true);\r\n\r\n // if called without an argument, toggle\r\n point.sliced = point.options.sliced = sliced = defined(sliced)\r\n ? sliced\r\n : !point.sliced;\r\n series.options.data[inArray(point, series.data)] = point.options; // update userOptions.data\r\n\r\n translation = sliced\r\n ? point.slicedTranslation\r\n : {\r\n translateX: 0,\r\n translateY: 0\r\n };\r\n\r\n point.graphic.animate(translation);\r\n\r\n if (point.shadowGroup) {\r\n point.shadowGroup.animate(translation);\r\n }\r\n }\r\n });\r\n\r\n /**\r\n * The Pie series class\r\n */\r\n var PieSeries = {\r\n type: \"pie\",\r\n isCartesian: false,\r\n pointClass: PiePoint,\r\n requireSorting: false,\r\n noSharedTooltip: true,\r\n trackerGroups: [\"group\", \"dataLabelsGroup\"],\r\n pointAttrToOptions: {\r\n // mapping between SVG attributes and the corresponding options\r\n stroke: \"borderColor\",\r\n \"stroke-width\": \"borderWidth\",\r\n fill: \"color\"\r\n },\r\n\r\n /**\r\n * Pies have one color each point\r\n */\r\n getColor: noop,\r\n\r\n /**\r\n * Animate the pies in\r\n */\r\n animate: function(init) {\r\n var series = this,\r\n points = series.points,\r\n startAngleRad = series.startAngleRad;\r\n\r\n if (!init) {\r\n each(points, function(point) {\r\n var graphic = point.graphic,\r\n args = point.shapeArgs;\r\n\r\n if (graphic) {\r\n // start values\r\n graphic.attr({\r\n r: series.center[3] / 2, // animate from inner radius (#779)\r\n start: startAngleRad,\r\n end: startAngleRad\r\n });\r\n\r\n // animate\r\n graphic.animate(\r\n {\r\n r: args.r,\r\n start: args.start,\r\n end: args.end\r\n },\r\n series.options.animation\r\n );\r\n }\r\n });\r\n\r\n // delete this function to allow it only once\r\n series.animate = null;\r\n }\r\n },\r\n\r\n /**\r\n * Extend the basic setData method by running processData and generatePoints immediately,\r\n * in order to access the points from the legend.\r\n */\r\n setData: function(data, redraw) {\r\n Series.prototype.setData.call(this, data, false);\r\n this.processData();\r\n this.generatePoints();\r\n if (pick(redraw, true)) {\r\n this.chart.redraw();\r\n }\r\n },\r\n\r\n /**\r\n * Extend the generatePoints method by adding total and percentage properties to each point\r\n */\r\n generatePoints: function() {\r\n var i,\r\n total = 0,\r\n points,\r\n len,\r\n point,\r\n ignoreHiddenPoint = this.options.ignoreHiddenPoint;\r\n\r\n Series.prototype.generatePoints.call(this);\r\n\r\n // Populate local vars\r\n points = this.points;\r\n len = points.length;\r\n\r\n // Get the total sum\r\n for (i = 0; i < len; i++) {\r\n point = points[i];\r\n total += ignoreHiddenPoint && !point.visible ? 0 : point.y;\r\n }\r\n this.total = total;\r\n\r\n // Set each point's properties\r\n for (i = 0; i < len; i++) {\r\n point = points[i];\r\n point.percentage = total > 0 ? (point.y / total) * 100 : 0;\r\n point.total = total;\r\n }\r\n },\r\n\r\n /**\r\n * Get the center of the pie based on the size and center options relative to the\r\n * plot area. Borrowed by the polar and gauge series types.\r\n */\r\n getCenter: function() {\r\n var options = this.options,\r\n chart = this.chart,\r\n slicingRoom = 2 * (options.slicedOffset || 0),\r\n handleSlicingRoom,\r\n plotWidth = chart.plotWidth - 2 * slicingRoom,\r\n plotHeight = chart.plotHeight - 2 * slicingRoom,\r\n centerOption = options.center,\r\n positions = [\r\n pick(centerOption[0], \"50%\"),\r\n pick(centerOption[1], \"50%\"),\r\n options.size || \"100%\",\r\n options.innerSize || 0\r\n ],\r\n smallestSize = mathMin(plotWidth, plotHeight),\r\n isPercent;\r\n\r\n return map(positions, function(length, i) {\r\n isPercent = /%$/.test(length);\r\n handleSlicingRoom = i < 2 || (i === 2 && isPercent);\r\n return (\r\n (isPercent\r\n ? // i == 0: centerX, relative to width\r\n // i == 1: centerY, relative to height\r\n // i == 2: size, relative to smallestSize\r\n // i == 4: innerSize, relative to smallestSize\r\n ([plotWidth, plotHeight, smallestSize, smallestSize][i] *\r\n pInt(length)) /\r\n 100\r\n : length) + (handleSlicingRoom ? slicingRoom : 0)\r\n );\r\n });\r\n },\r\n\r\n /**\r\n * Do translation for pie slices\r\n */\r\n translate: function(positions) {\r\n this.generatePoints();\r\n\r\n var series = this,\r\n cumulative = 0,\r\n precision = 1000, // issue #172\r\n options = series.options,\r\n slicedOffset = options.slicedOffset,\r\n connectorOffset = slicedOffset + options.borderWidth,\r\n start,\r\n end,\r\n angle,\r\n startAngle = options.startAngle || 0,\r\n startAngleRad = (series.startAngleRad =\r\n (mathPI / 180) * (startAngle - 90)),\r\n endAngleRad = (series.endAngleRad =\r\n (mathPI / 180) * ((options.endAngle || startAngle + 360) - 90)),\r\n circ = endAngleRad - startAngleRad, //2 * mathPI,\r\n points = series.points,\r\n radiusX, // the x component of the radius vector for a given point\r\n radiusY,\r\n labelDistance = options.dataLabels.distance,\r\n ignoreHiddenPoint = options.ignoreHiddenPoint,\r\n i,\r\n len = points.length,\r\n point;\r\n\r\n // Get positions - either an integer or a percentage string must be given.\r\n // If positions are passed as a parameter, we're in a recursive loop for adjusting\r\n // space for data labels.\r\n if (!positions) {\r\n series.center = positions = series.getCenter();\r\n }\r\n\r\n // utility for getting the x value from a given y, used for anticollision logic in data labels\r\n series.getX = function(y, left) {\r\n angle = math.asin(\r\n (y - positions[1]) / (positions[2] / 2 + labelDistance)\r\n );\r\n\r\n return (\r\n positions[0] +\r\n (left ? -1 : 1) *\r\n (mathCos(angle) * (positions[2] / 2 + labelDistance))\r\n );\r\n };\r\n\r\n // Calculate the geometry for each point\r\n for (i = 0; i < len; i++) {\r\n point = points[i];\r\n\r\n // set start and end angle\r\n start = startAngleRad + cumulative * circ;\r\n if (!ignoreHiddenPoint || point.visible) {\r\n cumulative += point.percentage / 100;\r\n }\r\n end = startAngleRad + cumulative * circ;\r\n\r\n // set the shape\r\n point.shapeType = \"arc\";\r\n point.shapeArgs = {\r\n x: positions[0],\r\n y: positions[1],\r\n r: positions[2] / 2,\r\n innerR: positions[3] / 2,\r\n start: mathRound(start * precision) / precision,\r\n end: mathRound(end * precision) / precision\r\n };\r\n\r\n // center for the sliced out slice\r\n angle = (end + start) / 2;\r\n if (angle > 0.75 * circ) {\r\n angle -= 2 * mathPI;\r\n }\r\n point.slicedTranslation = {\r\n translateX: mathRound(mathCos(angle) * slicedOffset),\r\n translateY: mathRound(mathSin(angle) * slicedOffset)\r\n };\r\n\r\n // set the anchor point for tooltips\r\n radiusX = (mathCos(angle) * positions[2]) / 2;\r\n radiusY = (mathSin(angle) * positions[2]) / 2;\r\n point.tooltipPos = [\r\n positions[0] + radiusX * 0.7,\r\n positions[1] + radiusY * 0.7\r\n ];\r\n\r\n point.half = angle < -mathPI / 2 || angle > mathPI / 2 ? 1 : 0;\r\n point.angle = angle;\r\n\r\n // set the anchor point for data labels\r\n connectorOffset = mathMin(connectorOffset, labelDistance / 2); // #1678\r\n point.labelPos = [\r\n positions[0] + radiusX + mathCos(angle) * labelDistance, // first break of connector\r\n positions[1] + radiusY + mathSin(angle) * labelDistance, // a/a\r\n positions[0] + radiusX + mathCos(angle) * connectorOffset, // second break, right outside pie\r\n positions[1] + radiusY + mathSin(angle) * connectorOffset, // a/a\r\n positions[0] + radiusX, // landing point for connector\r\n positions[1] + radiusY, // a/a\r\n labelDistance < 0 // alignment\r\n ? \"center\"\r\n : point.half\r\n ? \"right\"\r\n : \"left\", // alignment\r\n angle // center angle\r\n ];\r\n }\r\n },\r\n\r\n setTooltipPoints: noop,\r\n drawGraph: null,\r\n\r\n /**\r\n * Draw the data points\r\n */\r\n drawPoints: function() {\r\n var series = this,\r\n chart = series.chart,\r\n renderer = chart.renderer,\r\n groupTranslation,\r\n //center,\r\n graphic,\r\n //group,\r\n shadow = series.options.shadow,\r\n shadowGroup,\r\n shapeArgs;\r\n\r\n if (shadow && !series.shadowGroup) {\r\n series.shadowGroup = renderer.g(\"shadow\").add(series.group);\r\n }\r\n\r\n // draw the slices\r\n each(series.points, function(point) {\r\n graphic = point.graphic;\r\n shapeArgs = point.shapeArgs;\r\n shadowGroup = point.shadowGroup;\r\n\r\n // put the shadow behind all points\r\n if (shadow && !shadowGroup) {\r\n shadowGroup = point.shadowGroup = renderer\r\n .g(\"shadow\")\r\n .add(series.shadowGroup);\r\n }\r\n\r\n // if the point is sliced, use special translation, else use plot area traslation\r\n groupTranslation = point.sliced\r\n ? point.slicedTranslation\r\n : {\r\n translateX: 0,\r\n translateY: 0\r\n };\r\n\r\n //group.translate(groupTranslation[0], groupTranslation[1]);\r\n if (shadowGroup) {\r\n shadowGroup.attr(groupTranslation);\r\n }\r\n\r\n // draw the slice\r\n if (graphic) {\r\n graphic.animate(extend(shapeArgs, groupTranslation));\r\n }\r\n else {\r\n point.graphic = graphic = renderer\r\n .arc(shapeArgs)\r\n .setRadialReference(series.center)\r\n .attr(point.pointAttr[point.selected ? SELECT_STATE : NORMAL_STATE])\r\n .attr({ \"stroke-linejoin\": \"round\" })\r\n .attr(groupTranslation)\r\n .add(series.group)\r\n .shadow(shadow, shadowGroup);\r\n }\r\n\r\n // detect point specific visibility\r\n if (point.visible === false) {\r\n point.setVisible(false);\r\n }\r\n });\r\n },\r\n\r\n /**\r\n * Utility for sorting data labels\r\n */\r\n sortByAngle: function(points, sign) {\r\n points.sort(function(a, b) {\r\n return a.angle !== undefined && (b.angle - a.angle) * sign;\r\n });\r\n },\r\n\r\n /**\r\n * Override the base drawDataLabels method by pie specific functionality\r\n */\r\n drawDataLabels: function() {\r\n var series = this,\r\n data = series.data,\r\n point,\r\n chart = series.chart,\r\n options = series.options.dataLabels,\r\n connectorPadding = pick(options.connectorPadding, 10),\r\n connectorWidth = pick(options.connectorWidth, 1),\r\n plotWidth = chart.plotWidth,\r\n plotHeight = chart.plotHeight,\r\n connector,\r\n connectorPath,\r\n softConnector = pick(options.softConnector, true),\r\n distanceOption = options.distance,\r\n seriesCenter = series.center,\r\n radius = seriesCenter[2] / 2,\r\n centerY = seriesCenter[1],\r\n outside = distanceOption > 0,\r\n dataLabel,\r\n dataLabelWidth,\r\n labelPos,\r\n labelHeight,\r\n halves = [\r\n // divide the points into right and left halves for anti collision\r\n [], // right\r\n [] // left\r\n ],\r\n x,\r\n y,\r\n visibility,\r\n rankArr,\r\n i,\r\n j,\r\n overflow = [0, 0, 0, 0], // top, right, bottom, left\r\n sort = function(a, b) {\r\n return b.y - a.y;\r\n };\r\n\r\n // get out if not enabled\r\n if (!series.visible || (!options.enabled && !series._hasPointLabels)) {\r\n return;\r\n }\r\n\r\n // run parent method\r\n Series.prototype.drawDataLabels.apply(series);\r\n\r\n // arrange points for detection collision\r\n each(data, function(point) {\r\n if (point.dataLabel) {\r\n // it may have been cancelled in the base method (#407)\r\n halves[point.half].push(point);\r\n }\r\n });\r\n\r\n // assume equal label heights\r\n i = 0;\r\n while (!labelHeight && data[i]) {\r\n // #1569\r\n labelHeight =\r\n data[i] &&\r\n data[i].dataLabel &&\r\n (data[i].dataLabel.getBBox().height || 21); // 21 is for #968\r\n i++;\r\n }\r\n\r\n /* Loop over the points in each half, starting from the top and bottom\r\n * of the pie to detect overlapping labels.\r\n */\r\n i = 2;\r\n while (i--) {\r\n var slots = [],\r\n slotsLength,\r\n usedSlots = [],\r\n points = halves[i],\r\n pos,\r\n length = points.length,\r\n slotIndex;\r\n\r\n // Sort by angle\r\n series.sortByAngle(points, i - 0.5);\r\n\r\n // Only do anti-collision when we are outside the pie and have connectors (#856)\r\n if (distanceOption > 0) {\r\n // build the slots\r\n for (\r\n pos = centerY - radius - distanceOption;\r\n pos <= centerY + radius + distanceOption;\r\n pos += labelHeight\r\n ) {\r\n slots.push(pos);\r\n\r\n // visualize the slot\r\n /*\r\n\t\t\t\t\tvar slotX = series.getX(pos, i) + chart.plotLeft - (i ? 100 : 0),\r\n\t\t\t\t\t\tslotY = pos + chart.plotTop;\r\n\t\t\t\t\tif (!isNaN(slotX)) {\r\n\t\t\t\t\t\tchart.renderer.rect(slotX, slotY - 7, 100, labelHeight, 1)\r\n\t\t\t\t\t\t\t.attr({\r\n\t\t\t\t\t\t\t\t'stroke-width': 1,\r\n\t\t\t\t\t\t\t\tstroke: 'silver'\r\n\t\t\t\t\t\t\t})\r\n\t\t\t\t\t\t\t.add();\r\n\t\t\t\t\t\tchart.renderer.text('Slot '+ (slots.length - 1), slotX, slotY + 4)\r\n\t\t\t\t\t\t\t.attr({\r\n\t\t\t\t\t\t\t\tfill: 'silver'\r\n\t\t\t\t\t\t\t}).add();\r\n\t\t\t\t\t}\r\n\t\t\t\t\t*/\r\n }\r\n slotsLength = slots.length;\r\n\r\n // if there are more values than available slots, remove lowest values\r\n if (length > slotsLength) {\r\n // create an array for sorting and ranking the points within each quarter\r\n rankArr = [].concat(points);\r\n rankArr.sort(sort);\r\n j = length;\r\n while (j--) {\r\n rankArr[j].rank = j;\r\n }\r\n j = length;\r\n while (j--) {\r\n if (points[j].rank >= slotsLength) {\r\n points.splice(j, 1);\r\n }\r\n }\r\n length = points.length;\r\n }\r\n\r\n // The label goes to the nearest open slot, but not closer to the edge than\r\n // the label's index.\r\n for (j = 0; j < length; j++) {\r\n point = points[j];\r\n labelPos = point.labelPos;\r\n\r\n var closest = 9999,\r\n distance,\r\n slotI;\r\n\r\n // find the closest slot index\r\n for (slotI = 0; slotI < slotsLength; slotI++) {\r\n distance = mathAbs(slots[slotI] - labelPos[1]);\r\n if (distance < closest) {\r\n closest = distance;\r\n slotIndex = slotI;\r\n }\r\n }\r\n\r\n // if that slot index is closer to the edges of the slots, move it\r\n // to the closest appropriate slot\r\n if (slotIndex < j && slots[j] !== null) {\r\n // cluster at the top\r\n slotIndex = j;\r\n }\r\n else if (\r\n slotsLength < length - j + slotIndex &&\r\n slots[j] !== null\r\n ) {\r\n // cluster at the bottom\r\n slotIndex = slotsLength - length + j;\r\n while (slots[slotIndex] === null) {\r\n // make sure it is not taken\r\n slotIndex++;\r\n }\r\n }\r\n else {\r\n // Slot is taken, find next free slot below. In the next run, the next slice will find the\r\n // slot above these, because it is the closest one\r\n while (slots[slotIndex] === null) {\r\n // make sure it is not taken\r\n slotIndex++;\r\n }\r\n }\r\n\r\n usedSlots.push({ i: slotIndex, y: slots[slotIndex] });\r\n slots[slotIndex] = null; // mark as taken\r\n }\r\n // sort them in order to fill in from the top\r\n usedSlots.sort(sort);\r\n }\r\n\r\n // now the used slots are sorted, fill them up sequentially\r\n for (j = 0; j < length; j++) {\r\n var slot, naturalY;\r\n\r\n point = points[j];\r\n labelPos = point.labelPos;\r\n dataLabel = point.dataLabel;\r\n visibility = point.visible === false ? HIDDEN : VISIBLE;\r\n naturalY = labelPos[1];\r\n\r\n if (distanceOption > 0) {\r\n slot = usedSlots.pop();\r\n slotIndex = slot.i;\r\n\r\n // if the slot next to currrent slot is free, the y value is allowed\r\n // to fall back to the natural position\r\n y = slot.y;\r\n if (\r\n (naturalY > y && slots[slotIndex + 1] !== null) ||\r\n (naturalY < y && slots[slotIndex - 1] !== null)\r\n ) {\r\n y = naturalY;\r\n }\r\n }\r\n else {\r\n y = naturalY;\r\n }\r\n\r\n // get the x - use the natural x position for first and last slot, to prevent the top\r\n // and botton slice connectors from touching each other on either side\r\n x = options.justify\r\n ? seriesCenter[0] + (i ? -1 : 1) * (radius + distanceOption)\r\n : series.getX(\r\n slotIndex === 0 || slotIndex === slots.length - 1\r\n ? naturalY\r\n : y,\r\n i\r\n );\r\n\r\n // Record the placement and visibility\r\n dataLabel._attr = {\r\n visibility: visibility,\r\n align: labelPos[6]\r\n };\r\n dataLabel._pos = {\r\n x:\r\n x +\r\n options.x +\r\n ({ left: connectorPadding, right: -connectorPadding }[\r\n labelPos[6]\r\n ] || 0),\r\n y: y + options.y - 10 // 10 is for the baseline (label vs text)\r\n };\r\n dataLabel.connX = x;\r\n dataLabel.connY = y;\r\n\r\n // Detect overflowing data labels\r\n if (this.options.size === null) {\r\n dataLabelWidth = dataLabel.width;\r\n // Overflow left\r\n if (x - dataLabelWidth < connectorPadding) {\r\n overflow[3] = mathMax(\r\n mathRound(dataLabelWidth - x + connectorPadding),\r\n overflow[3]\r\n );\r\n\r\n // Overflow right\r\n }\r\n else if (x + dataLabelWidth > plotWidth - connectorPadding) {\r\n overflow[1] = mathMax(\r\n mathRound(x + dataLabelWidth - plotWidth + connectorPadding),\r\n overflow[1]\r\n );\r\n }\r\n\r\n // Overflow top\r\n if (y - labelHeight / 2 < 0) {\r\n overflow[0] = mathMax(\r\n mathRound(-y + labelHeight / 2),\r\n overflow[0]\r\n );\r\n\r\n // Overflow left\r\n }\r\n else if (y + labelHeight / 2 > plotHeight) {\r\n overflow[2] = mathMax(\r\n mathRound(y + labelHeight / 2 - plotHeight),\r\n overflow[2]\r\n );\r\n }\r\n }\r\n } // for each point\r\n } // for each half\r\n\r\n // Do not apply the final placement and draw the connectors until we have verified\r\n // that labels are not spilling over.\r\n if (arrayMax(overflow) === 0 || this.verifyDataLabelOverflow(overflow)) {\r\n // Place the labels in the final position\r\n this.placeDataLabels();\r\n\r\n // Draw the connectors\r\n if (outside && connectorWidth) {\r\n each(this.points, function(point) {\r\n connector = point.connector;\r\n labelPos = point.labelPos;\r\n dataLabel = point.dataLabel;\r\n\r\n if (dataLabel && dataLabel._pos) {\r\n visibility = dataLabel._attr.visibility;\r\n x = dataLabel.connX;\r\n y = dataLabel.connY;\r\n connectorPath = softConnector\r\n ? [\r\n M,\r\n x + (labelPos[6] === \"left\" ? 5 : -5),\r\n y, // end of the string at the label\r\n \"C\",\r\n x,\r\n y, // first break, next to the label\r\n 2 * labelPos[2] - labelPos[4],\r\n 2 * labelPos[3] - labelPos[5],\r\n labelPos[2],\r\n labelPos[3], // second break\r\n L,\r\n labelPos[4],\r\n labelPos[5] // base\r\n ]\r\n : [\r\n M,\r\n x + (labelPos[6] === \"left\" ? 5 : -5),\r\n y, // end of the string at the label\r\n L,\r\n labelPos[2],\r\n labelPos[3], // second break\r\n L,\r\n labelPos[4],\r\n labelPos[5] // base\r\n ];\r\n\r\n if (connector) {\r\n connector.animate({ d: connectorPath });\r\n connector.attr(\"visibility\", visibility);\r\n }\r\n else {\r\n point.connector = connector = series.chart.renderer\r\n .path(connectorPath)\r\n .attr({\r\n \"stroke-width\": connectorWidth,\r\n stroke: options.connectorColor || point.color || \"#606060\",\r\n visibility: visibility\r\n })\r\n .add(series.group);\r\n }\r\n }\r\n else if (connector) {\r\n point.connector = connector.destroy();\r\n }\r\n });\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Verify whether the data labels are allowed to draw, or we should run more translation and data\r\n * label positioning to keep them inside the plot area. Returns true when data labels are ready\r\n * to draw.\r\n */\r\n verifyDataLabelOverflow: function(overflow) {\r\n var center = this.center,\r\n options = this.options,\r\n centerOption = options.center,\r\n minSize = options.minSize || 80,\r\n newSize = minSize,\r\n ret;\r\n\r\n // Handle horizontal size and center\r\n if (centerOption[0] !== null) {\r\n // Fixed center\r\n newSize = mathMax(\r\n center[2] - mathMax(overflow[1], overflow[3]),\r\n minSize\r\n );\r\n }\r\n else {\r\n // Auto center\r\n newSize = mathMax(\r\n center[2] - overflow[1] - overflow[3], // horizontal overflow\r\n minSize\r\n );\r\n center[0] += (overflow[3] - overflow[1]) / 2; // horizontal center\r\n }\r\n\r\n // Handle vertical size and center\r\n if (centerOption[1] !== null) {\r\n // Fixed center\r\n newSize = mathMax(\r\n mathMin(newSize, center[2] - mathMax(overflow[0], overflow[2])),\r\n minSize\r\n );\r\n }\r\n else {\r\n // Auto center\r\n newSize = mathMax(\r\n mathMin(\r\n newSize,\r\n center[2] - overflow[0] - overflow[2] // vertical overflow\r\n ),\r\n minSize\r\n );\r\n center[1] += (overflow[0] - overflow[2]) / 2; // vertical center\r\n }\r\n\r\n // If the size must be decreased, we need to run translate and drawDataLabels again\r\n if (newSize < center[2]) {\r\n center[2] = newSize;\r\n this.translate(center);\r\n each(this.points, function(point) {\r\n if (point.dataLabel) {\r\n point.dataLabel._pos = null; // reset\r\n }\r\n });\r\n this.drawDataLabels();\r\n\r\n // Else, return true to indicate that the pie and its labels is within the plot area\r\n }\r\n else {\r\n ret = true;\r\n }\r\n return ret;\r\n },\r\n\r\n /**\r\n * Perform the final placement of the data labels after we have verified that they\r\n * fall within the plot area.\r\n */\r\n placeDataLabels: function() {\r\n each(this.points, function(point) {\r\n var dataLabel = point.dataLabel,\r\n _pos;\r\n\r\n if (dataLabel) {\r\n _pos = dataLabel._pos;\r\n if (_pos) {\r\n dataLabel.attr(dataLabel._attr);\r\n dataLabel[dataLabel.moved ? \"animate\" : \"attr\"](_pos);\r\n dataLabel.moved = true;\r\n }\r\n else if (dataLabel) {\r\n dataLabel.attr({ y: -999 });\r\n }\r\n }\r\n });\r\n },\r\n\r\n alignDataLabel: noop,\r\n\r\n /**\r\n * Draw point specific tracker objects. Inherit directly from column series.\r\n */\r\n drawTracker: ColumnSeries.prototype.drawTracker,\r\n\r\n /**\r\n * Use a simple symbol from column prototype\r\n */\r\n drawLegendSymbol: AreaSeries.prototype.drawLegendSymbol,\r\n\r\n /**\r\n * Pies don't have point marker symbols\r\n */\r\n getSymbol: noop\r\n };\r\n PieSeries = extendClass(Series, PieSeries);\r\n seriesTypes.pie = PieSeries;\r\n\r\n // global variables\r\n extend(Highcharts, {\r\n // Constructors\r\n Axis: Axis,\r\n Chart: Chart,\r\n Color: Color,\r\n Legend: Legend,\r\n Pointer: Pointer,\r\n Point: Point,\r\n Tick: Tick,\r\n Tooltip: Tooltip,\r\n Renderer: Renderer,\r\n Series: Series,\r\n SVGElement: SVGElement,\r\n SVGRenderer: SVGRenderer,\r\n\r\n // Various\r\n arrayMin: arrayMin,\r\n arrayMax: arrayMax,\r\n charts: charts,\r\n dateFormat: dateFormat,\r\n format: format,\r\n pathAnim: pathAnim,\r\n getOptions: getOptions,\r\n hasBidiBug: hasBidiBug,\r\n isTouchDevice: isTouchDevice,\r\n numberFormat: numberFormat,\r\n seriesTypes: seriesTypes,\r\n setOptions: setOptions,\r\n addEvent: addEvent,\r\n removeEvent: removeEvent,\r\n createElement: createElement,\r\n discardElement: discardElement,\r\n css: css,\r\n each: each,\r\n extend: extend,\r\n map: map,\r\n merge: merge,\r\n pick: pick,\r\n splat: splat,\r\n extendClass: extendClass,\r\n pInt: pInt,\r\n wrap: wrap,\r\n svg: hasSVG,\r\n canvas: useCanVG,\r\n vml: !hasSVG && !useCanVG,\r\n product: PRODUCT,\r\n version: VERSION\r\n });\r\n})();\r\n","/// \r\n/// \r\n/// \r\n/// \r\n/// \r\n\r\n(function() {\r\n var ns, sharedNs, velirParams;\r\n\r\n ns = window.nspace(\"ccc.viz.bar.models\");\r\n sharedNs = window.nspace(\"ccc.viz.shared.models\");\r\n velirParams = window.velir.datacenter.UrlParams;\r\n\r\n /**\r\n * Data response model is responsible for querying the server-side for data,\r\n * storing the response, and other views listen for the response to change\r\n * in order to be updated when new data is retrieved\r\n */\r\n ns.DataResponseModel = sharedNs.DataResponseModel.extend({\r\n getDataResponseOnChange: function() {\r\n this.getDataResponse();\r\n },\r\n\r\n getFilterString: function() {\r\n var params, filterStringNvc, filterString;\r\n\r\n params = window.ccc.viz.util.UrlParams;\r\n\r\n filterStringNvc = new window.velir.collections.NameValueCollection();\r\n filterStringNvc.add(\r\n params.indicator,\r\n this.selectorsModel.get(\"indicatorId\")\r\n );\r\n filterStringNvc.add(\r\n params.timeFrame,\r\n this.selectorsModel.get(\"timeFrameId\")\r\n );\r\n filterStringNvc.add(\r\n params.dataFormat,\r\n this.selectorsModel.get(\"dataFormatId\")\r\n );\r\n filterStringNvc.add(\r\n velirParams.characteristicId,\r\n this.selectorsModel.get(\"characteristicIds\")\r\n );\r\n filterStringNvc.add(\r\n velirParams.locationId,\r\n this.selectorsModel.get(\"locationIds\")\r\n );\r\n\r\n filterString = filterStringNvc.toQueryString();\r\n\r\n return filterString;\r\n },\r\n\r\n getDataParams: function(filterString) {\r\n return {\r\n filterString: filterString\r\n };\r\n },\r\n\r\n hasData: function() {\r\n return this.get(\"response\").hasData;\r\n }\r\n });\r\n})();\r\n","/// \r\n/// \r\n/// \r\n/// \r\n/// \r\n/// \r\n\r\n(function(Backbone, _) {\r\n \"use strict\";\r\n\r\n var ns, config;\r\n\r\n ns = window.nspace(\"ccc.viz.bar.views\");\r\n config = window.ccc.viz.bar.config.Config;\r\n\r\n ns.BarView = Backbone.View.extend({\r\n /**\r\n * These magic numbers are seeds to calculate the correct height of the bar chart div.\r\n * We calculate by assuming a certain amount of fixed overhead for the axes, then\r\n * assume a variable number of bars.\r\n */\r\n singleBarBaseHeight: 76,\r\n multiBarBaseHeight: 76,\r\n additionalBarHeight: 25,\r\n additionalMultiBarGroup: 29,\r\n\r\n /**\r\n * Since the SVG rectangle will go into navigation mode if the container div is too small to contain it,\r\n * we have to calculate the height of the legend and adjust the height accordingly.\r\n */\r\n\r\n /**\r\n * A fixed amount of padding overhead for each legend.\r\n */\r\n legendOverhead: 33,\r\n /**\r\n * The height of an individual legend span with the current font settings.\r\n */\r\n legendItemHeight: 18,\r\n\r\n initialize: function(options) {\r\n _.bindAll(this);\r\n\r\n this.selectorsModel = options.selectorsModel;\r\n\r\n this.model.on(\"change\", this.render);\r\n\r\n $(window).on(\"scroll\", this.updateLegendPosition);\r\n },\r\n\r\n render: function() {\r\n var options;\r\n\r\n if (!this.selectorsModel.areModelArraysValid()) {\r\n return;\r\n }\r\n\r\n options = $.extend(\r\n true,\r\n {},\r\n config.defaultHighchartsConfig,\r\n this.model.get(\"response\").highCharts\r\n );\r\n this.formatYAxisLabels(options);\r\n this.adjustForSingleCharacteristic(options);\r\n this.sizeBarChartContainer(options);\r\n options.series = options.series.reverse();\r\n options.colors = options.colors.reverse();\r\n this.orderChartColors(options);\r\n\r\n this.$(\".bar-chart\").highcharts(options);\r\n\r\n this.updateLegendPosition();\r\n },\r\n\r\n /**\r\n * Adjust the highcharts options for single characteristic charts. The bar config file defaults to multi-bar settings.\r\n */\r\n adjustForSingleCharacteristic: function(options) {\r\n var singleCharacteristicConfig;\r\n\r\n if (this.isMultiBarChart()) {\r\n return;\r\n }\r\n\r\n singleCharacteristicConfig =\r\n window.ccc.viz.bar.config.SingleCharacteristicConfig;\r\n $.extend(true, options, singleCharacteristicConfig);\r\n },\r\n\r\n /**\r\n * Adds a formatter, where necessary, for the yAxis labels.\r\n */\r\n formatYAxisLabels: function(options) {\r\n if (\r\n !(options.tooltip || {}).valuePrefix &&\r\n !(options.tooltip || {}).valueSuffix\r\n ) {\r\n return;\r\n }\r\n\r\n window.createNestedObject(options, [\"yAxis\", \"labels\", \"formatter\"]);\r\n\r\n options.yAxis.labels.formatter = function() {\r\n var newValue = this.value;\r\n if (options.tooltip.valueSuffix === \"%\") {\r\n newValue = Math.round(this.value * 10000) / 100;\r\n }\n else if (options.tooltip.valuePrefix === \"$\") {\r\n if (this.value >= 1000) {\r\n newValue = Math.round(this.value / 100) / 10 + \"k\";\r\n }\n else {\r\n newValue = this.value;\r\n }\r\n }\r\n return (\r\n (options.tooltip.valuePrefix || \"\") +\r\n newValue +\r\n (options.tooltip.valueSuffix || \"\")\r\n );\r\n };\r\n },\r\n\r\n /**\r\n * Updates the position of the legend relative to the window scroll position.\r\n */\r\n updateLegendPosition: function() {\r\n var $container,\r\n $legend,\r\n $rect,\r\n isIE8,\r\n $svg,\r\n svgOffset,\r\n windowScrollTop,\r\n newY,\r\n containerOffset,\r\n containerHeight,\r\n legendHeight,\r\n legendTranslation;\r\n\r\n $container = this.$(\".highcharts-container\");\r\n $legend = this.$(\".highcharts-legend\");\r\n $rect = $legend.find(\"rect\").first();\r\n isIE8 = $rect.length === 0; // IE8 condition\r\n\r\n windowScrollTop = $(window).scrollTop();\r\n containerHeight = $container.height();\r\n\r\n if (isIE8) {\r\n containerOffset = $container.offset();\r\n if (!containerOffset) {\r\n return;\r\n }\r\n newY = windowScrollTop - containerOffset.top;\r\n\r\n legendHeight = 22; // height of initial margin\r\n // get the height of all the spans and add them\r\n $legend.find(\"span\").each(function() {\r\n legendHeight += $(this).height();\r\n });\r\n\r\n if (newY > containerHeight - legendHeight) {\r\n return;\r\n }\n else if (newY > 10) {\r\n // scrolled past the top\r\n $legend.css(\"top\", newY + \"px\");\r\n }\n else {\r\n $legend.css(\"top\", \"0px\");\r\n }\r\n\r\n return;\r\n }\r\n\r\n $svg = $legend.closest(\"svg\");\r\n svgOffset = $svg.offset();\r\n\r\n if (!svgOffset || $legend.length === 0) {\r\n return;\r\n }\r\n\r\n newY = windowScrollTop - svgOffset.top + 10;\r\n legendHeight = +$rect.attr(\"height\");\r\n legendTranslation = $legend.attr(\"transform\");\r\n if (!legendTranslation) {\r\n return;\r\n }\n else if (newY >= containerHeight - legendHeight) {\r\n return;\r\n }\n else if (newY > 10 && newY < containerHeight - legendHeight) {\r\n $legend.attr(\r\n \"transform\",\r\n legendTranslation.replace(\r\n /(translate\\(\\d*[, ])\\d*(\\))/gi,\r\n \"$1\" + newY + \"$2\"\r\n )\r\n );\r\n }\n else {\r\n $legend.attr(\r\n \"transform\",\r\n legendTranslation.replace(\r\n /(translate\\(\\d*[, ])\\d*(\\))/gi,\r\n \"$1\" + 10 + \"$2\"\r\n )\r\n );\r\n }\r\n },\r\n\r\n sizeBarChartContainer: function(options) {\r\n var height;\r\n\r\n height = this.calculateCorrectBarHeight();\r\n height = this.adjustForLegendHeight(height, options);\r\n this.$(\".bar-chart\").height(height);\r\n },\r\n\r\n /**\r\n * Highcharts doesn't try to find an ideal bar chart size. It tries to squeeze everything into the container size that you set, or if you don't set the size explicitly,\r\n * it doesn't go past a certain fixed height. So the point of this method is to get a good chart size that works for all charts.\r\n */\r\n calculateCorrectBarHeight: function() {\r\n if (this.isMultiBarChart()) {\r\n return this.calculateMultiBarHeight();\r\n }\r\n return this.calculateSingleBarHeight();\r\n },\r\n\r\n /**\r\n * Gets the optimal multi-bar chart height.\r\n */\r\n calculateMultiBarHeight: function() {\r\n var locationCount, characteristicCount, height;\r\n\r\n locationCount = this.selectorsModel.get(\"locationIds\").length;\r\n characteristicCount = this.selectorsModel.get(\"characteristicIds\").length;\r\n\r\n // We use locationCount - 1 because the initial bar group heights are already assumed in the base height.\r\n // We use characteristicCount - 2 because the initial individual bar heights already assume there are two characteristics per group.\r\n height =\r\n this.multiBarBaseHeight + // The height of a single bar multi bar chart.\r\n (locationCount - 1) * this.additionalMultiBarGroup + // Gets the overhead associated with all additional location groups.\r\n (characteristicCount - 1) *\r\n Math.max(locationCount, 1) *\r\n this.additionalBarHeight; // Gets the size of extra characteristics for each new group, including the original location group;\r\n\r\n return height;\r\n },\r\n\r\n /**\r\n * Gets the optimal single-bar chart height.\r\n */\r\n calculateSingleBarHeight: function() {\r\n var locationCount, height;\r\n\r\n locationCount = this.selectorsModel.get(\"locationIds\").length;\r\n\r\n // We use locationCount - 1 as a multiplier because the initial bar height is already assumed in the base height.\r\n height =\r\n this.singleBarBaseHeight +\r\n (locationCount - 1) * this.additionalBarHeight;\r\n\r\n return height;\r\n },\r\n\r\n /**\r\n * Determines whether we're dealing with a single or multi bar chart.\r\n */\r\n isMultiBarChart: function() {\r\n var characteristicIds;\r\n\r\n characteristicIds = this.selectorsModel.get(\"characteristicIds\");\r\n if (characteristicIds && characteristicIds[0] !== \"a\") {\r\n return true;\r\n }\r\n\r\n return false;\r\n },\r\n\r\n /**\r\n * Ordering the colors so that regardless of the number of series in the chart, we return a consistent ordering of colors.\r\n */\r\n orderChartColors: function(options) {\r\n if (!options || !options.colors || !options.series) {\r\n return;\r\n }\r\n\r\n options.colors = _.map(options.colors, function(color, index) {\r\n var arrayLength, arrayDiff;\r\n\r\n arrayLength = options.colors.length;\r\n arrayDiff = options.series.length - options.colors.length;\r\n return index + (arrayLength - arrayDiff) < options.colors.length\r\n ? options.colors[index + (arrayLength - arrayDiff)]\r\n : options.colors[index - arrayDiff];\r\n });\r\n },\r\n\r\n /**\r\n * Adjusts the height of the div container based on the legend size.\r\n * @param height The current height of the container div.\r\n */\r\n adjustForLegendHeight: function(height, options) {\r\n var self, maxLegendSize, legendLines, actualLegendSize;\r\n\r\n // Return the original height if there's no legend.\r\n if (options.legend.enabled === false) {\r\n return height;\r\n }\r\n\r\n self = this;\r\n legendLines = 0;\r\n maxLegendSize = height - this.legendOverhead;\r\n _.each(this.selectorsModel.get(\"characteristicIds\"), function(id) {\r\n var indicatorId, name, modifiedName;\r\n\r\n legendLines++;\r\n indicatorId = self.selectorsModel.get(\"indicatorId\");\r\n name = _.filter(\r\n self.selectorsModel.selectorInfo.selectors[indicatorId]\r\n .characteristics,\r\n function(characteristic) {\r\n return +characteristic.id === +id;\r\n }\r\n )[0].name;\r\n\r\n modifiedName = config.defaultHighchartsConfig.legend.labelFormatterHelper(\r\n name\r\n );\r\n // Uses jQuery to find the number of br elements in the modified name text. Any *real* performance issues here?\r\n legendLines = legendLines + $(modifiedName).filter(\"br\").length;\r\n });\r\n\r\n actualLegendSize = legendLines * this.legendItemHeight;\r\n if (maxLegendSize - actualLegendSize >= 0) {\r\n return height;\r\n }\r\n\r\n return height + actualLegendSize - maxLegendSize;\r\n }\r\n });\r\n})(Backbone, _);\r\n","(function($, _) {\r\n var ns = window.nspace(\"ccc.viz.bar.views\");\r\n\r\n /**\r\n * The source/definition/notes that appears below the map\r\n */\r\n ns.HeaderView = Backbone.View.extend({\r\n el: \"#bar-chart-container\",\r\n name: \"Bar header view\",\r\n templateSelector: \"#bar-header-notes-template\",\r\n\r\n initialize: function(options) {\r\n _.bindAll(this, \"render\", \"loadTemplate\", \"getInitialRenderPromise\");\r\n\r\n this.initialRenderPromise = $.Deferred();\r\n\r\n this.selectorsModel = options.selectorsModel;\r\n\r\n this.model.on(\"change\", this.render);\r\n },\r\n\r\n getInitialRenderPromise: function() {\r\n return this.initialRenderPromise;\r\n },\r\n\r\n loadTemplate: function() {\r\n // Get the underscore template\r\n if (!this.template) {\r\n var $tmpl = $(this.templateSelector);\r\n if ($tmpl.length === 0) {\r\n throw \"Could not find the \" +\r\n this.name +\r\n \" template: \" +\r\n this.templateSelector;\r\n }\r\n\r\n // Pre-compile and cache the template\r\n this.template = _.template($tmpl.html());\r\n }\r\n },\r\n\r\n render: function() {\r\n var self, selectorInfo, indicatorName, dataFormatName, templateData;\r\n\r\n self = this;\r\n\r\n // Verify this selector's container is present\r\n if (this.$el.length === 0) {\r\n throw \"Could not find the \" + this.name + \" container: \" + this.el;\r\n }\r\n\r\n // Load the template\r\n this.loadTemplate();\r\n\r\n // Only rerender if the indicator has change from the last render\r\n if (!this.shouldDrawHeader()) {\r\n this.currentIndicatorId = this.selectorsModel.get(\"indicatorId\");\r\n this.dataFormatId = this.selectorsModel.get(\"dataFormatId\");\r\n this.locationIds = this.selectorsModel.get(\"locationIds\");\r\n this.characteristicIds = this.selectorsModel.get(\"characteristicIds\");\r\n return;\r\n }\r\n\r\n this.currentIndicatorId = this.selectorsModel.get(\"indicatorId\");\r\n this.dataFormatId = this.selectorsModel.get(\"dataFormatId\");\r\n this.locationIds = this.selectorsModel.get(\"locationIds\");\r\n this.characteristicIds = this.selectorsModel.get(\"characteristicIds\");\r\n\r\n // Render the text\r\n selectorInfo = this.selectorsModel.selectorInfo;\r\n indicatorName = _.filter(selectorInfo.indicators, function(indicator) {\r\n return indicator.id === +self.selectorsModel.get(\"indicatorId\");\r\n })[0].name;\r\n dataFormatName = _.filter(\r\n selectorInfo.selectors[self.selectorsModel.get(\"indicatorId\")]\r\n .dataFormats,\r\n function(dataFormat) {\r\n return dataFormat.id === +self.selectorsModel.get(\"dataFormatId\");\r\n }\r\n )[0].name;\r\n templateData = {\r\n indicatorName: indicatorName,\r\n dataFormatName: dataFormatName\r\n };\r\n\r\n // Render the output\r\n self\r\n .$(\"h4.bar-header\")\r\n .html(self.template(templateData))\r\n // Animate the transition\r\n .hide()\r\n .fadeIn(function() {\r\n self.initialRenderPromise.resolve();\r\n });\r\n },\r\n\r\n shouldDrawHeader: function() {\r\n // Only rerender if the indicator has change from the last render\r\n if (this.selectorsModel.get(\"indicatorId\") !== this.currentIndicatorId) {\r\n return true;\r\n }\r\n\r\n if (this.selectorsModel.get(\"dataFormatId\") !== this.dataFormatId) {\r\n return true;\r\n }\r\n\r\n if (this.locationIds && !this.locationIds.length) {\r\n return true;\r\n }\r\n\r\n if (this.characteristicIds && !this.characteristicIds.length) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n });\r\n})(jQuery, _);\r\n","/// \r\n\r\n(function() {\r\n var ns;\r\n\r\n ns = window.nspace(\"ccc.viz.bar.views\");\r\n\r\n /**\r\n * A friendly no data message view that appears if a user unselects all checkboxes.\r\n */\r\n ns.NoBarDataView = window.ccc.viz.shared.views.NoDataView.extend({\r\n el: \"#bar-chart-container\",\r\n name: \"No bar data view\",\r\n templateSelector: \"#no-bar-data-template\",\r\n\r\n render: function() {\r\n var self;\r\n\r\n self = this;\r\n if (self.selectorsModel.areModelArraysValid() && self.model.hasData()) {\r\n return;\r\n }\r\n\r\n // Verify this selector's container is present\r\n if (self.$el.length === 0) {\r\n throw \"Could not find the \" + self.name + \" container: \" + self.el;\r\n }\r\n\r\n // Load the template\r\n self.loadTemplate();\r\n\r\n // Render the output\r\n self.$el.html(self.template());\r\n\r\n // Animate the transition\r\n self.$el.hide().fadeIn(function() {\r\n self.initialRenderPromise.resolve();\r\n });\r\n }\r\n });\r\n})();\r\n","/// \r\n/// \r\n/// \r\n\r\n(function($, _) {\r\n var ns, selectorNs, sharedNs;\r\n\r\n ns = window.nspace(\"ccc.viz.bar.views\");\r\n selectorNs = window.nspace(\"ccc.viz.selectors\");\r\n sharedNs = window.nspace(\"ccc.viz.shared\");\r\n\r\n ns.SelectorsView = sharedNs.views.SelectorsView.extend({\r\n initializeView: function() {\r\n // Expose this (presumably one-and-only) instance globally so that other components\r\n // can call \"public\" methods and get selector information, such as for building data summaries.\r\n // TODO: What's a better way to architect this?\r\n ns.instances = { SelectorsView: this };\r\n\r\n this.model.on(\"change\", this.updateDataSummary);\r\n },\r\n\r\n initializeSelectors: function() {\r\n this.allSelectors = [\r\n // Breakdown\r\n (this.breakdownSelectorView = new selectorNs.MultipleBreakdownSelectorView(\r\n {\r\n model: this.model\r\n }\r\n )),\r\n // Location\r\n (this.locationSelectorView = new selectorNs.LocationSelectorView({\r\n model: this.model\r\n })),\r\n // Data Type\r\n (this.dataTypeSelectorView = new selectorNs.DataTypeSelectorView({\r\n model: this.model,\r\n getSelectorInfoFunc: this.getSelectorInfoOrThrow\r\n })),\r\n // TimeFrame\r\n (this.timeFrameSelectorView = new selectorNs.TimeFrameSelectorView({\r\n model: this.model,\r\n getSelectorInfoFunc: this.getSelectorInfoOrThrow\r\n }))\r\n ];\r\n },\r\n\r\n getIndicatorSpecificSelectors: function() {\r\n return [this.dataTypeSelectorView, this.timeFrameSelectorView];\r\n },\r\n\r\n updateDataSummary: function() {\r\n $(\"#data-summary\").text(this.getDataSummary());\r\n },\r\n\r\n renderSelectors: function(selectorInfo) {\r\n var indicatorSpecificSelectors, indicatorSelectorInfo;\r\n\r\n // Selectors that are specific to a single indicator. This is all selectors\r\n // besides the breakdown selector.\r\n indicatorSpecificSelectors = this.getIndicatorSpecificSelectors();\r\n\r\n // Breakdown selector\r\n this.breakdownSelectorView.render(selectorInfo);\r\n\r\n // The other selectors all expect indicator-specific selector info\r\n indicatorSelectorInfo =\r\n selectorInfo.selectors[this.model.get(\"indicatorId\")];\r\n for (var i = 0; i < indicatorSpecificSelectors.length; i++) {\r\n // Render the selector\r\n indicatorSpecificSelectors[i].render(indicatorSelectorInfo);\r\n }\r\n\r\n var info = this.shapeLocations(selectorInfo, indicatorSelectorInfo);\r\n // Location selector\r\n this.locationSelectorView.render(info);\r\n },\r\n\r\n shapeLocations: function(selectorInfo, indicatorSelectorInfo) {\r\n var orphanLocations, locationTypes;\r\n\r\n locationTypes = _(indicatorSelectorInfo.locationTypes)\r\n .sortBy(function(locationType) {\r\n return locationType.displayOrder;\r\n })\r\n .value();\r\n\r\n orphanLocations = _(selectorInfo.locations)\r\n .filter(function(location) {\r\n return !location.parent;\r\n })\r\n .value();\r\n\r\n _.each(locationTypes, function(locationType) {\r\n locationType.locations = _(selectorInfo.locations)\r\n .filter(function(location) {\r\n return !!location.parent && location.parent.id === locationType.id;\r\n })\r\n .sortBy(function(location) {\r\n return location.name;\r\n })\r\n .value();\r\n });\r\n\r\n return {\r\n orphanLocations: orphanLocations,\r\n locationTypes: locationTypes\r\n };\r\n }\r\n });\r\n})(jQuery, _);\r\n"]}