app/assets/javascripts/highcharts.js in highcharts-rails-4.1.4 vs app/assets/javascripts/highcharts.js in highcharts-rails-4.1.5

- old
+ new

@@ -1,10 +1,10 @@ // ==ClosureCompiler== // @compilation_level SIMPLE_OPTIMIZATIONS /** - * @license Highcharts JS v4.1.4 (2015-03-10) + * @license Highcharts JS v4.1.5 (2015-04-13) * * (c) 2009-2014 Torstein Honsi * * License: www.highcharts.com/license */ @@ -54,11 +54,11 @@ timeUnits, noop = function () { return UNDEFINED; }, charts = [], chartCount = 0, PRODUCT = 'Highcharts', - VERSION = '4.1.4', + VERSION = '4.1.5', // some constants for frequently used strings DIV = 'div', ABSOLUTE = 'absolute', RELATIVE = 'relative', @@ -90,10 +90,12 @@ getHours, getDay, getDate, getMonth, getFullYear, + setMilliseconds, + setSeconds, setMinutes, setHours, setDate, setMonth, setFullYear, @@ -1257,12 +1259,12 @@ thousandsSep: ' ' }, global: { useUTC: true, //timezoneOffset: 0, - canvasToolsURL: 'http://code.highcharts.com/4.1.4/modules/canvas-tools.js', - VMLRadialGradientURL: 'http://code.highcharts.com/4.1.4/gfx/vml-radial-gradient.png' + canvasToolsURL: 'http://code.highcharts.com/4.1.5/modules/canvas-tools.js', + VMLRadialGradientURL: 'http://code.highcharts.com/4.1.5/gfx/vml-radial-gradient.png' }, chart: { //animation: true, //alignTicks: false, //reflow: true, @@ -1611,21 +1613,23 @@ pick(seconds, 0) ).getTime(); } return d; }; - getMinutes = GET + 'Minutes'; - getHours = GET + 'Hours'; - getDay = GET + 'Day'; - getDate = GET + 'Date'; - getMonth = GET + 'Month'; - getFullYear = GET + 'FullYear'; - setMinutes = SET + 'Minutes'; - setHours = SET + 'Hours'; - setDate = SET + 'Date'; - setMonth = SET + 'Month'; - setFullYear = SET + 'FullYear'; + getMinutes = GET + 'Minutes'; + getHours = GET + 'Hours'; + getDay = GET + 'Day'; + getDate = GET + 'Date'; + getMonth = GET + 'Month'; + getFullYear = GET + 'FullYear'; + setMilliseconds = SET + 'Milliseconds'; + setSeconds = SET + 'Seconds'; + setMinutes = SET + 'Minutes'; + setHours = SET + 'Hours'; + setDate = SET + 'Date'; + setMonth = SET + 'Month'; + setFullYear = SET + 'FullYear'; } /** * Merge the default options with custom options and return the new options structure @@ -1782,11 +1786,11 @@ SVGElement.prototype = { // Default base for animation opacity: 1, // For labels, these CSS properties are applied to the <text> node directly - textProps: ['fontSize', 'fontWeight', 'fontFamily', 'color', + textProps: ['fontSize', 'fontWeight', 'fontFamily', 'fontStyle', 'color', 'lineHeight', 'width', 'textDecoration', 'textShadow'], /** * Initialize the SVG renderer * @param {Object} renderer @@ -5910,11 +5914,14 @@ slotWidth -= rightPos - rightBound; xy.x = rightBound; label.attr({ align: 'right' }); } - if (labelWidth > slotWidth) { + // If the label width exceeds the available space, set a text width to be + // picked up below. Also, if a width has been set before, we need to set a new + // one because the reported labelWidth will be limited by the box (#3938). + if (labelWidth > slotWidth || (axis.autoRotation && label.styles.width)) { textWidth = slotWidth; } // Add ellipsis to prevent rotated labels to be clipped against the edge of the chart @@ -7888,11 +7895,11 @@ }; if (horiz) { autoRotation = defined(rotationOption) ? [rotationOption] : - slotSize < 80 && !labelOptions.staggerLines && !labelOptions.step && labelOptions.autoRotation; + slotSize < pick(labelOptions.autoRotationLimit, 80) && !labelOptions.staggerLines && !labelOptions.step && labelOptions.autoRotation; if (autoRotation) { // Loop over the given autoRotation options, and determine which gives the best score. The // best score is that with the lowest number of steps and a rotation closest to horizontal. @@ -7977,11 +7984,15 @@ i = tickPositions.length; while (!horiz && i--) { pos = tickPositions[i]; label = ticks[pos].label; if (label) { - if (this.len / tickPositions.length - 4 < label.getBBox().height) { + // Reset ellipsis in order to get the correct bounding box (#4070) + if (label.styles.textOverflow === 'ellipsis') { + label.css({ textOverflow: 'clip' }); + } + if (label.getBBox().height > this.len / tickPositions.length - (labelMetrics.h - labelMetrics.f)) { label.specCss = { textOverflow: 'ellipsis' }; } } } } @@ -8579,15 +8590,15 @@ minDate = new Date(min - getTZOffset(min)), interval = normalizedInterval.unitRange, count = normalizedInterval.count; if (defined(min)) { // #1300 - minDate.setMilliseconds(interval >= timeUnits.second ? 0 : + minDate[setMilliseconds](interval >= timeUnits.second ? 0 : // #3935 count * mathFloor(minDate.getMilliseconds() / count)); // #3652, #3654 if (interval >= timeUnits.second) { // second - minDate.setSeconds(interval >= timeUnits.minute ? 0 : + minDate[setSeconds](interval >= timeUnits.minute ? 0 : // #3935 count * mathFloor(minDate.getSeconds() / count)); } if (interval >= timeUnits.minute) { // minute minDate[setMinutes](interval >= timeUnits.hour ? 0 : @@ -9063,10 +9074,11 @@ getPosition: function (boxWidth, boxHeight, point) { var chart = this.chart, distance = this.distance, ret = {}, + h = point.h, swapped, first = ['y', chart.chartHeight, boxHeight, point.plotY + chart.plotTop], second = ['x', chart.chartWidth, boxWidth, point.plotX + chart.plotLeft], // The far side is right or bottom preferFarSide = pick(point.ttBelow, (chart.inverted && !point.negative) || (!chart.inverted && point.negative)), @@ -9083,13 +9095,13 @@ if (preferFarSide && roomRight) { ret[dim] = alignedRight; } else if (!preferFarSide && roomLeft) { ret[dim] = alignedLeft; } else if (roomLeft) { - ret[dim] = alignedLeft; + ret[dim] = alignedLeft - h < 0 ? alignedLeft : alignedLeft - h; } else if (roomRight) { - ret[dim] = alignedRight; + ret[dim] = alignedRight + h + innerSize > outerSize ? alignedRight : alignedRight + h; } else { return false; } }, /** @@ -9251,12 +9263,17 @@ // set the stroke color of the box borderColor = options.borderColor || point.color || currentSeries.color || '#606060'; label.attr({ stroke: borderColor }); - - tooltip.updatePosition({ plotX: x, plotY: y, negative: point.negative, ttBelow: point.ttBelow }); + tooltip.updatePosition({ + plotX: x, + plotY: y, + negative: point.negative, + ttBelow: point.ttBelow, + h: (point.shapeArgs && point.shapeArgs.height) || 0 + }); this.isHidden = false; } fireEvent(chart, 'tooltipRefresh', { text: text, @@ -9518,12 +9535,10 @@ //point, //points, hoverPoint = chart.hoverPoint, hoverSeries = chart.hoverSeries, i, - trueXkd, - trueX, //j, distance = chart.chartWidth, rdistance = chart.chartWidth, anchor, noSharedTooltip, @@ -9539,12 +9554,17 @@ series = []; } } } + // If it has a hoverPoint and that series requires direct touch (like columns), + // use the hoverPoint (#3899). Otherwise, search the k-d tree. + if (!shared && hoverSeries && hoverSeries.directTouch && hoverPoint) { + kdpoint = hoverPoint; + // Handle shared tooltip or cases where a series is not yet hovered - if (!(hoverSeries && hoverSeries.noSharedTooltip) && (shared || !hoverSeries)) { // #3821 + } else { // Find nearest points on all series each(series, function (s) { // Skip hidden series noSharedTooltip = s.noSharedTooltip && shared; if (s.visible && !noSharedTooltip && pick(s.options.enableMouseTracking, true)) { // #3821 @@ -9555,34 +9575,27 @@ } }); // Find absolute nearest point each(kdpoints, function (p) { if (p && defined(p.plotX) && defined(p.plotY)) { - if ((p.dist.distX < distance) || ((p.dist.distX === distance || p.series.kdDimensions > 1) && p.dist.distR < rdistance)) { + if ((p.dist.distX < distance) || ((p.dist.distX === distance || p.series.kdDimensions > 1) && + p.dist.distR < rdistance)) { distance = p.dist.distX; rdistance = p.dist.distR; kdpoint = p; } } - }); - - // Handle non-shared tooltips - } else { - // If it has a hoverPoint and that series requires direct touch (like columns), use the hoverPoint (#3899). - // Otherwise, search the k-d tree (like scatter). - kdpoint = (hoverSeries.directTouch && hoverPoint) || (hoverSeries && hoverSeries.searchPoint(e)); + }); } // Refresh tooltip for kdpoint if new hover point or tooltip was hidden // #3926 if (kdpoint && (kdpoint !== hoverPoint || (tooltip && tooltip.isHidden))) { // Draw tooltip if necessary if (shared && !kdpoint.series.noSharedTooltip) { i = kdpoints.length; - trueXkd = kdpoint.clientX; while (i--) { - trueX = kdpoints[i].clientX; - if (kdpoints[i].x !== kdpoint.x || trueX !== trueXkd || (kdpoints[i].series.noSharedTooltip || false)) { + if (kdpoints[i].clientX !== kdpoint.clientX || kdpoints[i].series.noSharedTooltip) { kdpoints.splice(i, 1); } } if (kdpoints.length && tooltip) { tooltip.refresh(kdpoints, e); @@ -9591,12 +9604,13 @@ // do mouseover on all points except the closest each(kdpoints, function (point) { if (point !== kdpoint) { point.onMouseOver(e); } - }); - kdpoint.onMouseOver(e); // #3919 do mouseover on the closest point last to ensure it is the hoverpoint + }); + // #3919, #3985 do mouseover on the closest point last to ensure it is the hoverpoint + ((hoverSeries && hoverSeries.directTouch && hoverPoint) || kdpoint).onMouseOver(e); } else { if (tooltip) { tooltip.refresh(kdpoint, e); } kdpoint.onMouseOver(e); @@ -10346,11 +10360,11 @@ touches[e.pointerId].target = e.currentTarget; } }); }, onDocumentPointerUp: function (e) { - translateMSPointer(e, 'onContainerTouchEnd', 'touchend', function (e) { + translateMSPointer(e, 'onDocumentTouchEnd', 'touchend', function (e) { delete touches[e.pointerId]; }); }, /** @@ -10364,11 +10378,11 @@ }); // Disable default IE actions for pinch and such on chart element wrap(Pointer.prototype, 'init', function (proceed, chart, options) { proceed.call(this, chart, options); - if (this.hasZoom || this.followTouchMove) { + if (this.hasZoom) { // #4014 css(chart.container, { '-ms-touch-action': NONE, 'touch-action': NONE }); } @@ -10655,11 +10669,12 @@ }) .add(item.legendGroup); // Get the baseline for the first item - the font size is equal for all if (!legend.baseline) { - legend.baseline = renderer.fontMetrics(itemStyle.fontSize, li).f + 3 + itemMarginTop; + legend.fontMetrics = renderer.fontMetrics(itemStyle.fontSize, li); + legend.baseline = legend.fontMetrics.f + 3 + itemMarginTop; li.attr('y', legend.baseline); } // Draw the legend symbol inside the group box series.drawLegendSymbol(legend, item); @@ -10689,10 +10704,11 @@ // if the item exceeds the width, start a new line if (horizontal && legend.itemX - initialItemX + itemWidth > (widthOption || (chart.chartWidth - 2 * padding - initialItemX - options.x))) { legend.itemX = initialItemX; legend.itemY += itemMarginTop + legend.lastLineHeight + itemMarginBottom; + legend.lastLineHeight = 0; // reset for next line (#915, #3976) } // If the item exceeds the height, start a new column /*if (!horizontal && legend.itemY + options.y + itemHeight > chart.chartHeight - spacingTop - spacingBottom) { legend.itemY = legend.initialItemY; @@ -11092,15 +11108,15 @@ * * @param {Object} legend The legend object * @param {Object} item The series (this) or point */ drawRectangle: function (legend, item) { - var symbolHeight = legend.options.symbolHeight || 12; - + var symbolHeight = legend.options.symbolHeight || legend.fontMetrics.f; + item.legendSymbol = this.chart.renderer.rect( 0, - legend.baseline - 5 - (symbolHeight / 2), + legend.baseline - symbolHeight + 1, // #3988 legend.symbolWidth, symbolHeight, legend.options.symbolRadius || 0 ).attr({ zIndex: 3 @@ -11117,16 +11133,15 @@ drawLineMarker: function (legend) { var options = this.options, markerOptions = options.marker, radius, - legendOptions = legend.options, legendSymbol, symbolWidth = legend.symbolWidth, renderer = this.chart.renderer, legendItemGroup = this.legendGroup, - verticalCenter = legend.baseline - mathRound(renderer.fontMetrics(legendOptions.itemStyle.fontSize, this.legendItem).b * 0.3), + verticalCenter = legend.baseline - mathRound(legend.fontMetrics.b * 0.3), attr; // Draw the line if (options.lineWidth) { attr = { @@ -12363,11 +12378,11 @@ axis.setScale(); }); chart.getAxisMargins(); // If the plot area size has changed significantly, calculate tick positions again - redoHorizontal = tempWidth / chart.plotWidth > 1.2; + redoHorizontal = tempWidth / chart.plotWidth > 1.1; redoVertical = tempHeight / chart.plotHeight > 1.1; if (redoHorizontal || redoVertical) { chart.maxTicks = null; // reset for second pass @@ -12711,22 +12726,23 @@ * Transform number or array configs into objects */ optionsToObject: function (options) { var ret = {}, series = this.series, - pointArrayMap = series.pointArrayMap || ['y'], + keys = series.options.keys, // docs: http://jsfiddle.net/ch4v7n8v/1 + pointArrayMap = keys || series.pointArrayMap || ['y'], valueCount = pointArrayMap.length, firstItemType, i = 0, j = 0; if (typeof options === 'number' || options === null) { ret[pointArrayMap[0]] = options; } else if (isArray(options)) { // with leading x value - if (options.length > valueCount) { + if (!keys && options.length > valueCount) { firstItemType = typeof options[0]; if (firstItemType === 'string') { ret.name = options[0]; } else if (firstItemType === 'number') { ret.x = options[0]; @@ -13557,12 +13573,10 @@ xExtremes = xAxis.getExtremes(), // #2117, need to compensate for log X axis xMin = xExtremes.min, xMax = xExtremes.max, validValue, withinRange, - dataMin, - dataMax, x, y, i, j; @@ -13592,12 +13606,12 @@ } else { activeYData[activeCounter++] = y; } } } - this.dataMin = pick(dataMin, arrayMin(activeYData)); - this.dataMax = pick(dataMax, arrayMax(activeYData)); + this.dataMin = arrayMin(activeYData); + this.dataMax = arrayMax(activeYData); }, /** * Translate data points from raw data values to chart specific positioning data * needed later in drawPoints, drawGraph and drawTracker. @@ -13749,11 +13763,11 @@ this.group.clip(animation || seriesClipBox ? clipRect : chart.clipRect); this.markerGroup.clip(markerClipRect); this.sharedClipKey = sharedClipKey; } - // Remove the shared clipping rectancgle when all series are shown + // Remove the shared clipping rectangle when all series are shown if (!animation) { clipRect.count -= 1; if (clipRect.count <= 0 && sharedClipKey && chart[sharedClipKey]) { if (!seriesClipBox) { chart[sharedClipKey] = chart[sharedClipKey].destroy(); @@ -14046,10 +14060,14 @@ attr.fillColor = point.color; } if (!defaultLineColor) { attr.lineColor = point.color; // Bubbles take point color, line markers use white } + // Color is explicitly set to null or undefined (#1288, #4068) + if (normalOptions.hasOwnProperty('color') && !normalOptions.color) { + delete normalOptions.color; + } pointAttr[NORMAL_STATE] = series.convertAttribs(extend(attr, normalOptions), seriesPointAttr[NORMAL_STATE]); // inherit from point normal and series hover pointAttr[HOVER_STATE] = series.convertAttribs( stateOptions[HOVER_STATE], @@ -14121,23 +14139,22 @@ series.points = null; // Clear the animation timeout if we are destroying the series during initial animation clearTimeout(series.animationTimeout); - // destroy all SVGElements associated to the series - each(['area', 'graph', 'dataLabelsGroup', 'group', 'markerGroup', 'tracker', - 'graphNeg', 'areaNeg', 'posClip', 'negClip'], function (prop) { - if (series[prop]) { + // Destroy all SVGElements associated to the series + for (prop in series) { + if (series[prop] instanceof SVGElement && !series[prop].survive) { // Survive provides a hook for not destroying // issue 134 workaround destroy = issue134 && prop === 'group' ? 'hide' : 'destroy'; series[prop][destroy](); } - }); + } // remove from hoverSeries if (chart.hoverSeries === series) { chart.hoverSeries = null; } @@ -14250,11 +14267,11 @@ graphPath = this.getGraphPath(), fillColor = (this.fillGraph && this.color) || NONE, // polygon series use filled graph zones = this.zones; each(zones, function (threshold, i) { - props.push(['colorGraph' + i, threshold.color || series.color, threshold.dashStyle || options.dashStyle]); + props.push(['zoneGraph' + i, threshold.color || series.color, threshold.dashStyle || options.dashStyle]); }); // Draw the graph each(props, function (prop, i) { var graphKey = prop[0], @@ -14308,18 +14325,28 @@ ignoreZones = false; if (zones.length && (graph || area)) { // The use of the Color Threshold assumes there are no gaps // so it is safe to hide the original graph and area - graph.hide(); - if (area) { area.hide(); } + if (graph) { + graph.hide(); + } + if (area) { + area.hide(); + } // Create the clips each(zones, function (threshold, i) { translatedFrom = pick(translatedTo, (reversed ? (horiz ? chart.plotWidth : 0) : (horiz ? 0 : axis.toPixels(axis.min)))); translatedTo = mathRound(axis.toPixels(pick(threshold.value, axis.max), true)); + if (axis.isXAxis) { + translatedFrom = translatedFrom > translatedTo ? translatedTo : translatedFrom; //#4006 from should be less or equal then to + } else { + translatedFrom = translatedFrom < translatedTo ? translatedTo : translatedFrom; //#4006 from should be less or equal then to + } + if (ignoreZones) { translatedFrom = translatedTo = axis.toPixels(axis.max); } if (axis.isXAxis) { @@ -14367,14 +14394,16 @@ if (clips[i]) { clips[i].animate(clipAttr); } else { clips[i] = renderer.clipRect(clipAttr); - series['colorGraph' + i].clip(clips[i]); + if (graph) { + series['zoneGraph' + i].clip(clips[i]); + } if (area) { - series['colorArea' + i].clip(clips[i]); + series['zoneArea' + i].clip(clips[i]); } } // if this zone extends out of the axis, ignore the others ignoreZones = threshold.value > axis.max; }); @@ -14609,23 +14638,23 @@ * KD Tree && PointSearching Implementation */ kdDimensions: 1, kdTree: null, - kdAxisArray: ['plotX', 'plotY'], + kdAxisArray: ['clientX', 'plotY'], kdComparer: 'distX', searchPoint: function (e) { var series = this, xAxis = series.xAxis, yAxis = series.yAxis, inverted = series.chart.inverted; - e.plotX = inverted ? xAxis.len - e.chartY + xAxis.pos : e.chartX - xAxis.pos; - e.plotY = inverted ? yAxis.len - e.chartX + yAxis.pos : e.chartY - yAxis.pos; - - return this.searchKDTree(e); + return this.searchKDTree({ + clientX: inverted ? xAxis.len - e.chartY + xAxis.pos : e.chartX - xAxis.pos, + plotY: inverted ? yAxis.len - e.chartX + yAxis.pos : e.chartY - yAxis.pos + }); }, buildKDTree: function () { var series = this, dimensions = series.kdDimensions; @@ -14814,11 +14843,12 @@ setOffset: function (xOffset, xWidth) { var stackItem = this, axis = stackItem.axis, chart = axis.chart, inverted = chart.inverted, - neg = this.isNegative, // special treatment is needed for negative stacks + reversed = axis.reversed, + neg = (this.isNegative && !reversed) || (!this.isNegative && reversed), // #4056 y = axis.translate(axis.usePercentage ? 100 : this.total, 0, 0, 0, 1), // stack value translated mapped to chart coordinates yZero = axis.translate(0), // stack origin h = mathAbs(y - yZero), // stack height x = chart.xAxis[0].translate(this.x) + xOffset, // stack x position plotHeight = chart.plotHeight, @@ -15271,24 +15301,29 @@ graph = series.graph, area = series.area, chart = series.chart, names = series.xAxis && series.xAxis.names, currentShift = (graph && graph.shift) || 0, + shiftShapes = ['graph', 'area'], dataOptions = seriesOptions.data, point, isInTheMiddle, xData = series.xData, - x, - i; + i, + x; setAnimation(animation, chart); // Make graph animate sideways if (shift) { - each([graph, area, series.graphNeg, series.areaNeg], function (shape) { - if (shape) { - shape.shift = currentShift + 1; + i = series.zones.length; + while (i--) { + shiftShapes.push('zoneGraph' + i, 'zoneArea' + i); + } + each(shiftShapes, function (shape) { + if (series[shape]) { + series[shape].shift = currentShift + 1; } }); } if (area) { area.isArea = true; // needed in animation, both with and without shift @@ -15742,11 +15777,11 @@ options = this.options, zones = this.zones, props = [['area', this.color, options.fillColor]]; // area name, main color, fill color each(zones, function (threshold, i) { - props.push(['colorArea' + i, threshold.color || series.color, threshold.fillColor || options.fillColor]); + props.push(['zoneArea' + i, threshold.color || series.color, threshold.fillColor || options.fillColor]); }); each(props, function (prop) { var areaKey = prop[0], area = series[areaKey]; @@ -16081,12 +16116,15 @@ seriesBarW = series.barW = mathMax(pointWidth, 1 + 2 * borderWidth), // postprocessed for border width pointXOffset = series.pointXOffset = metrics.offset, xCrisp = -(borderWidth % 2 ? 0.5 : 0), yCrisp = borderWidth % 2 ? 0.5 : 1; - if (chart.renderer.isVML && chart.inverted) { - yCrisp += 1; + if (chart.inverted) { + translatedThreshold -= 0.5; // #3355 + if (chart.renderer.isVML) { + yCrisp += 1; + } } // When the pointPadding is 0, we want the columns to be packed tightly, so we allow individual // columns to have individual sizes. When pointPadding is greater, we strive for equal-width // columns (#2694). @@ -16104,20 +16142,22 @@ barW = seriesBarW, barY = mathMin(plotY, yBottom), right, bottom, fromTop, + up, barH = mathMax(plotY, yBottom) - barY; // Handle options.minPointLength if (mathAbs(barH) < minPointLength) { if (minPointLength) { barH = minPointLength; + up = (!yAxis.reversed && !point.negative) || (yAxis.reversed && point.negative); barY = mathRound(mathAbs(barY - translatedThreshold) > minPointLength ? // stacked yBottom - minPointLength : // keep position - translatedThreshold - (yAxis.translate(point.y, 0, 1, 0, 1) <= translatedThreshold ? minPointLength : 0)); // use exact yAxis.translation (#1485) + translatedThreshold - (up ? minPointLength : 0)); // #1485, #4051 } } // Cache for access in polar point.barX = barX; @@ -16395,42 +16435,46 @@ /** * Toggle the visibility of the pie slice * @param {Boolean} vis Whether to show the slice or not. If undefined, the * visibility is toggled */ - setVisible: function (vis) { + setVisible: function (vis, force) { var point = this, series = point.series, chart = series.chart, doRedraw = !series.isDirty && series.options.ignoreHiddenPoint; - // if called without an argument, toggle visibility - point.visible = point.options.visible = vis = vis === UNDEFINED ? !point.visible : vis; - series.options.data[inArray(point, series.data)] = point.options; // update userOptions.data + // Only if the value has changed + if (vis !== point.visible || force) { + + // If called without an argument, toggle visibility + point.visible = point.options.visible = vis = vis === UNDEFINED ? !point.visible : vis; + series.options.data[inArray(point, series.data)] = point.options; // update userOptions.data - // Show and hide associated elements - each(['graphic', 'dataLabel', 'connector', 'shadowGroup'], function (key) { - if (point[key]) { - point[key][vis ? 'show' : 'hide'](true); - } - }); + // Show and hide associated elements + each(['graphic', 'dataLabel', 'connector', 'shadowGroup'], function (key) { + if (point[key]) { + point[key][vis ? 'show' : 'hide'](true); + } + }); - if (point.legendItem) { - if (chart.hasRendered) { - series.updateTotals(); - chart.legend.clearItems(); - if (!doRedraw) { - chart.legend.render(); + if (point.legendItem) { + if (chart.hasRendered) { + series.updateTotals(); + chart.legend.clearItems(); + if (!doRedraw) { + chart.legend.render(); + } } + chart.legend.colorizeItem(point, vis); } - chart.legend.colorizeItem(point, vis); - } - // Handle ignore hidden slices - if (doRedraw) { - series.isDirty = true; - chart.redraw(); + // Handle ignore hidden slices + if (doRedraw) { + series.isDirty = true; + chart.redraw(); + } } }, /** * Set or toggle whether the slice is cut out from the pie @@ -16513,11 +16557,11 @@ args = point.shapeArgs; if (graphic) { // start values graphic.attr({ - r: series.center[3] / 2, // animate from inner radius (#779) + r: point.startR || (series.center[3] / 2), // animate from inner radius (#779) start: startAngleRad, end: startAngleRad }); // animate @@ -16725,10 +16769,13 @@ .add(series.group); } // draw the slices each(series.points, function (point) { + + var visible = point.options.visible; + graphic = point.graphic; shapeArgs = point.shapeArgs; shadowGroup = point.shadowGroup; // put the shadow behind all points @@ -16764,13 +16811,13 @@ .attr(groupTranslation) .add(series.group) .shadow(shadow, shadowGroup); } - // detect point specific visibility (#2430) - if (point.visible !== undefined) { - point.setVisible(point.visible); + // Detect point specific visibility (#2430) + if (visible !== undefined) { + point.setVisible(visible, true); } }); }, @@ -17300,11 +17347,11 @@ var slot, naturalY; point = points[j]; labelPos = point.labelPos; dataLabel = point.dataLabel; - visibility = point.visible === false ? HIDDEN : VISIBLE; + visibility = point.visible === false ? HIDDEN : 'inherit'; naturalY = labelPos[1]; if (distanceOption > 0) { slot = usedSlots.pop(); slotIndex = slot.i; @@ -17321,10 +17368,11 @@ y = naturalY; } // get the x - use the natural x position for first and last slot, to prevent the top // and botton slice connectors from touching each other on either side + // Problem: Should check that it makes sense - http://jsfiddle.net/highcharts/n1y6ngxz/ x = options.justify ? seriesCenter[0] + (i ? -1 : 1) * (radius + distanceOption) : series.getX(y === centerY - radius - distanceOption || y === centerY + radius + distanceOption ? naturalY : y, i); @@ -17563,11 +17611,11 @@ } /** - * Highcharts JS v4.1.4 (2015-03-10) + * Highcharts JS v4.1.5 (2015-04-13) * Highcharts module to hide overlapping data labels. This module is included by default in Highmaps. * * (c) 2010-2014 Torstein Honsi * * License: www.highcharts.com/license @@ -18331,14 +18379,14 @@ */ setState: function (state) { var series = this, options = series.options, graph = series.graph, - graphNeg = series.graphNeg, stateOptions = options.states, lineWidth = options.lineWidth, - attribs; + attribs, + i = 0; state = state || NORMAL_STATE; if (series.state !== state) { series.state = state; @@ -18346,20 +18394,21 @@ if (stateOptions[state] && stateOptions[state].enabled === false) { return; } if (state) { - lineWidth = (stateOptions[state].lineWidth || lineWidth) + (stateOptions[state].lineWidthPlus || 0); + lineWidth = stateOptions[state].lineWidth || lineWidth + (stateOptions[state].lineWidthPlus || 0); // #4035 } if (graph && !graph.dashstyle) { // hover is turned off for dashed lines in VML attribs = { 'stroke-width': lineWidth }; // use attr because animate will cause any other animation on the graph to stop graph.attr(attribs); - if (graphNeg) { - graphNeg.attr(attribs); + while (series['zoneGraph' + i]) { + series['zoneGraph' + i].attr(attribs); + i = i + 1; } } } },