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;
}
}
}
},