plotly.js 2.6.1 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * plotly.js (gl3d) v2.6.1
2
+ * plotly.js (gl3d) v2.7.0
3
3
  * Copyright 2012-2021, Plotly, Inc.
4
4
  * All rights reserved.
5
5
  * Licensed under the MIT license
@@ -22653,6 +22653,19 @@ function makeColorBarData(gd) {
22653
22653
  }
22654
22654
 
22655
22655
  function drawColorBar(g, opts, gd) {
22656
+ var len = opts.len;
22657
+ var lenmode = opts.lenmode;
22658
+ var thickness = opts.thickness;
22659
+ var thicknessmode = opts.thicknessmode;
22660
+ var outlinewidth = opts.outlinewidth;
22661
+ var borderwidth = opts.borderwidth;
22662
+ var xanchor = opts.xanchor;
22663
+ var yanchor = opts.yanchor;
22664
+ var xpad = opts.xpad;
22665
+ var ypad = opts.ypad;
22666
+ var optsX = opts.x;
22667
+ var optsY = opts.y;
22668
+
22656
22669
  var fullLayout = gd._fullLayout;
22657
22670
  var gs = fullLayout._size;
22658
22671
 
@@ -22682,42 +22695,41 @@ function drawColorBar(g, opts, gd) {
22682
22695
  // when the colorbar itself is pushing the margins.
22683
22696
  // but then the fractional size is calculated based on the
22684
22697
  // actual graph size, so that the axes will size correctly.
22685
- var thickPx = Math.round(opts.thickness * (opts.thicknessmode === 'fraction' ? gs.w : 1));
22698
+ var thickPx = Math.round(thickness * (thicknessmode === 'fraction' ? gs.w : 1));
22686
22699
  var thickFrac = thickPx / gs.w;
22687
- var lenPx = Math.round(opts.len * (opts.lenmode === 'fraction' ? gs.h : 1));
22700
+ var lenPx = Math.round(len * (lenmode === 'fraction' ? gs.h : 1));
22688
22701
  var lenFrac = lenPx / gs.h;
22689
- var xpadFrac = opts.xpad / gs.w;
22690
- var yExtraPx = (opts.borderwidth + opts.outlinewidth) / 2;
22691
- var ypadFrac = opts.ypad / gs.h;
22702
+ var xpadFrac = xpad / gs.w;
22703
+ var yExtraPx = (borderwidth + outlinewidth) / 2;
22704
+ var ypadFrac = ypad / gs.h;
22692
22705
 
22693
22706
  // x positioning: do it initially just for left anchor,
22694
22707
  // then fix at the end (since we don't know the width yet)
22695
- var xLeft = Math.round(opts.x * gs.w + opts.xpad);
22708
+ var uPx = Math.round(optsX * gs.w + xpad);
22696
22709
  // for dragging... this is getting a little muddled...
22697
- var xLeftFrac = opts.x - thickFrac * ({center: 0.5, right: 1}[opts.xanchor] || 0);
22710
+ var uFrac = optsX - thickFrac * ({center: 0.5, right: 1}[xanchor] || 0);
22698
22711
 
22699
22712
  // y positioning we can do correctly from the start
22700
- var yBottomFrac = opts.y + lenFrac * (({top: -0.5, bottom: 0.5}[opts.yanchor] || 0) - 0.5);
22701
- var yBottomPx = Math.round(gs.h * (1 - yBottomFrac));
22702
- var yTopPx = yBottomPx - lenPx;
22713
+ var vFrac = optsY + lenFrac * (({top: -0.5, bottom: 0.5}[yanchor] || 0) - 0.5);
22714
+ var vPx = Math.round(gs.h * (1 - vFrac));
22703
22715
 
22704
22716
  // stash a few things for makeEditable
22705
22717
  opts._lenFrac = lenFrac;
22706
22718
  opts._thickFrac = thickFrac;
22707
- opts._xLeftFrac = xLeftFrac;
22708
- opts._yBottomFrac = yBottomFrac;
22719
+ opts._uFrac = uFrac;
22720
+ opts._vFrac = vFrac;
22709
22721
 
22710
22722
  // stash mocked axis for contour label formatting
22711
22723
  var ax = opts._axis = mockColorBarAxis(gd, opts, zrange);
22712
22724
 
22713
22725
  // position can't go in through supplyDefaults
22714
22726
  // because that restricts it to [0,1]
22715
- ax.position = opts.x + xpadFrac + thickFrac;
22727
+ ax.position = optsX + xpadFrac + thickFrac;
22716
22728
 
22717
22729
  if(['top', 'bottom'].indexOf(titleSide) !== -1) {
22718
22730
  ax.title.side = titleSide;
22719
- ax.titlex = opts.x + xpadFrac;
22720
- ax.titley = yBottomFrac + (title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
22731
+ ax.titlex = optsX + xpadFrac;
22732
+ ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
22721
22733
  }
22722
22734
 
22723
22735
  if(line.color && opts.tickmode === 'auto') {
@@ -22725,7 +22737,7 @@ function drawColorBar(g, opts, gd) {
22725
22737
  ax.tick0 = levelsIn.start;
22726
22738
  var dtick = levelsIn.size;
22727
22739
  // expand if too many contours, so we don't get too many ticks
22728
- var autoNtick = Lib.constrain((yBottomPx - yTopPx) / 50, 4, 15) + 1;
22740
+ var autoNtick = Lib.constrain(lenPx / 50, 4, 15) + 1;
22729
22741
  var dtFactor = (zrange[1] - zrange[0]) / ((opts.nticks || autoNtick) * dtick);
22730
22742
  if(dtFactor > 1) {
22731
22743
  var dtexp = Math.pow(10, Math.floor(Math.log(dtFactor) / Math.LN10));
@@ -22743,8 +22755,8 @@ function drawColorBar(g, opts, gd) {
22743
22755
  // set domain after init, because we may want to
22744
22756
  // allow it outside [0,1]
22745
22757
  ax.domain = [
22746
- yBottomFrac + ypadFrac,
22747
- yBottomFrac + lenFrac - ypadFrac
22758
+ vFrac + ypadFrac,
22759
+ vFrac + lenFrac - ypadFrac
22748
22760
  ];
22749
22761
 
22750
22762
  ax.setScale();
@@ -22785,15 +22797,15 @@ function drawColorBar(g, opts, gd) {
22785
22797
  // draw the title so we know how much room it needs
22786
22798
  // when we squish the axis. This one only applies to
22787
22799
  // top or bottom titles, not right side.
22788
- var x = gs.l + (opts.x + xpadFrac) * gs.w;
22800
+ var x = gs.l + (optsX + xpadFrac) * gs.w;
22789
22801
  var fontSize = ax.title.font.size;
22790
22802
  var y;
22791
22803
 
22792
22804
  if(titleSide === 'top') {
22793
- y = (1 - (yBottomFrac + lenFrac - ypadFrac)) * gs.h +
22805
+ y = (1 - (vFrac + lenFrac - ypadFrac)) * gs.h +
22794
22806
  gs.t + 3 + fontSize * 0.75;
22795
22807
  } else {
22796
- y = (1 - (yBottomFrac + ypadFrac)) * gs.h +
22808
+ y = (1 - (vFrac + ypadFrac)) * gs.h +
22797
22809
  gs.t - 3 - fontSize * 0.25;
22798
22810
  }
22799
22811
  drawTitle(ax._id + 'title', {
@@ -22832,7 +22844,7 @@ function drawColorBar(g, opts, gd) {
22832
22844
  // squish the axis top to make room for the title
22833
22845
  var titleGroup = g.select('.' + cn.cbtitle);
22834
22846
  var titleText = titleGroup.select('text');
22835
- var titleTrans = [-opts.outlinewidth / 2, opts.outlinewidth / 2];
22847
+ var titleTrans = [-outlinewidth / 2, outlinewidth / 2];
22836
22848
  var mathJaxNode = titleGroup
22837
22849
  .select('.h' + ax._id + 'title-math-group')
22838
22850
  .node();
@@ -22904,7 +22916,7 @@ function drawColorBar(g, opts, gd) {
22904
22916
  // Colorbar cannot currently support opacities so we
22905
22917
  // use an opaque fill even when alpha channels present
22906
22918
  var fillEl = d3.select(this).attr({
22907
- x: xLeft,
22919
+ x: uPx,
22908
22920
  width: Math.max(thickPx, 2),
22909
22921
  y: d3.min(z),
22910
22922
  height: Math.max(d3.max(z) - d3.min(z), 2),
@@ -22928,7 +22940,7 @@ function drawColorBar(g, opts, gd) {
22928
22940
  lines.exit().remove();
22929
22941
  lines.each(function(d) {
22930
22942
  d3.select(this)
22931
- .attr('d', 'M' + xLeft + ',' +
22943
+ .attr('d', 'M' + uPx + ',' +
22932
22944
  (Math.round(ax.c2p(d)) + (line.width / 2) % 1) + 'h' + thickPx)
22933
22945
  .call(Drawing.lineGroupStyle, line.width, lineColormap(d), line.dash);
22934
22946
  });
@@ -22936,8 +22948,8 @@ function drawColorBar(g, opts, gd) {
22936
22948
  // force full redraw of labels and ticks
22937
22949
  axLayer.selectAll('g.' + ax._id + 'tick,path').remove();
22938
22950
 
22939
- var shift = xLeft + thickPx +
22940
- (opts.outlinewidth || 0) / 2 - (opts.ticks === 'outside' ? 1 : 0);
22951
+ var shift = uPx + thickPx +
22952
+ (outlinewidth || 0) / 2 - (opts.ticks === 'outside' ? 1 : 0);
22941
22953
 
22942
22954
  var vals = Axes.calcTicks(ax);
22943
22955
  var tickSign = Axes.getTickSigns(ax)[2];
@@ -22962,9 +22974,9 @@ function drawColorBar(g, opts, gd) {
22962
22974
  // TODO: why are we redrawing multiple times now with this?
22963
22975
  // I guess autoMargin doesn't like being post-promise?
22964
22976
  function positionCB() {
22965
- var innerWidth = thickPx + opts.outlinewidth / 2;
22977
+ var innerThickness = thickPx + outlinewidth / 2;
22966
22978
  if(ax.ticklabelposition.indexOf('inside') === -1) {
22967
- innerWidth += Drawing.bBox(axLayer.node()).width;
22979
+ innerThickness += Drawing.bBox(axLayer.node()).width;
22968
22980
  }
22969
22981
 
22970
22982
  titleEl = titleCont.select('text');
@@ -22979,66 +22991,65 @@ function drawColorBar(g, opts, gd) {
22979
22991
  // (except for top/bottom mathjax, above)
22980
22992
  // but the weird gs.l is because the titleunshift
22981
22993
  // transform gets removed by Drawing.bBox
22982
- titleWidth = Drawing.bBox(titleCont.node()).right - xLeft - gs.l;
22994
+ titleWidth = Drawing.bBox(titleCont.node()).right - uPx - gs.l;
22983
22995
  }
22984
- innerWidth = Math.max(innerWidth, titleWidth);
22996
+ innerThickness = Math.max(innerThickness, titleWidth);
22985
22997
  }
22986
22998
 
22987
- var outerwidth = 2 * opts.xpad + innerWidth + opts.borderwidth + opts.outlinewidth / 2;
22988
- var outerheight = yBottomPx - yTopPx;
22999
+ var outerThickness = 2 * xpad + innerThickness + borderwidth + outlinewidth / 2;
22989
23000
 
22990
23001
  g.select('.' + cn.cbbg).attr({
22991
- x: xLeft - opts.xpad - (opts.borderwidth + opts.outlinewidth) / 2,
22992
- y: yTopPx - yExtraPx,
22993
- width: Math.max(outerwidth, 2),
22994
- height: Math.max(outerheight + 2 * yExtraPx, 2)
23002
+ x: uPx - xpad - (borderwidth + outlinewidth) / 2,
23003
+ y: vPx - lenPx - yExtraPx,
23004
+ width: Math.max(outerThickness, 2),
23005
+ height: Math.max(lenPx + 2 * yExtraPx, 2)
22995
23006
  })
22996
23007
  .call(Color.fill, opts.bgcolor)
22997
23008
  .call(Color.stroke, opts.bordercolor)
22998
- .style('stroke-width', opts.borderwidth);
23009
+ .style('stroke-width', borderwidth);
22999
23010
 
23000
23011
  g.selectAll('.' + cn.cboutline).attr({
23001
- x: xLeft,
23002
- y: yTopPx + opts.ypad + (titleSide === 'top' ? titleHeight : 0),
23012
+ x: uPx,
23013
+ y: vPx - lenPx + ypad + (titleSide === 'top' ? titleHeight : 0),
23003
23014
  width: Math.max(thickPx, 2),
23004
- height: Math.max(outerheight - 2 * opts.ypad - titleHeight, 2)
23015
+ height: Math.max(lenPx - 2 * ypad - titleHeight, 2)
23005
23016
  })
23006
23017
  .call(Color.stroke, opts.outlinecolor)
23007
23018
  .style({
23008
23019
  fill: 'none',
23009
- 'stroke-width': opts.outlinewidth
23020
+ 'stroke-width': outlinewidth
23010
23021
  });
23011
23022
 
23012
23023
  // fix positioning for xanchor!='left'
23013
- var xoffset = ({center: 0.5, right: 1}[opts.xanchor] || 0) * outerwidth;
23024
+ var xoffset = ({center: 0.5, right: 1}[xanchor] || 0) * outerThickness;
23014
23025
  g.attr('transform', strTranslate(gs.l - xoffset, gs.t));
23015
23026
 
23016
23027
  // auto margin adjustment
23017
23028
  var marginOpts = {};
23018
- var tFrac = FROM_TL[opts.yanchor];
23019
- var bFrac = FROM_BR[opts.yanchor];
23020
- if(opts.lenmode === 'pixels') {
23021
- marginOpts.y = opts.y;
23022
- marginOpts.t = outerheight * tFrac;
23023
- marginOpts.b = outerheight * bFrac;
23029
+ var tFrac = FROM_TL[yanchor];
23030
+ var bFrac = FROM_BR[yanchor];
23031
+ if(lenmode === 'pixels') {
23032
+ marginOpts.y = optsY;
23033
+ marginOpts.t = lenPx * tFrac;
23034
+ marginOpts.b = lenPx * bFrac;
23024
23035
  } else {
23025
23036
  marginOpts.t = marginOpts.b = 0;
23026
- marginOpts.yt = opts.y + opts.len * tFrac;
23027
- marginOpts.yb = opts.y - opts.len * bFrac;
23037
+ marginOpts.yt = optsY + len * tFrac;
23038
+ marginOpts.yb = optsY - len * bFrac;
23028
23039
  }
23029
23040
 
23030
- var lFrac = FROM_TL[opts.xanchor];
23031
- var rFrac = FROM_BR[opts.xanchor];
23032
- if(opts.thicknessmode === 'pixels') {
23033
- marginOpts.x = opts.x;
23034
- marginOpts.l = outerwidth * lFrac;
23035
- marginOpts.r = outerwidth * rFrac;
23041
+ var lFrac = FROM_TL[xanchor];
23042
+ var rFrac = FROM_BR[xanchor];
23043
+ if(thicknessmode === 'pixels') {
23044
+ marginOpts.x = optsX;
23045
+ marginOpts.l = outerThickness * lFrac;
23046
+ marginOpts.r = outerThickness * rFrac;
23036
23047
  } else {
23037
- var extraThickness = outerwidth - thickPx;
23048
+ var extraThickness = outerThickness - thickPx;
23038
23049
  marginOpts.l = extraThickness * lFrac;
23039
23050
  marginOpts.r = extraThickness * rFrac;
23040
- marginOpts.xl = opts.x - opts.thickness * lFrac;
23041
- marginOpts.xr = opts.x + opts.thickness * rFrac;
23051
+ marginOpts.xl = optsX - thickness * lFrac;
23052
+ marginOpts.xr = optsX + thickness * rFrac;
23042
23053
  }
23043
23054
 
23044
23055
  Plots.autoMargin(gd, opts._id, marginOpts);
@@ -23069,9 +23080,9 @@ function makeEditable(g, opts, gd) {
23069
23080
  moveFn: function(dx, dy) {
23070
23081
  g.attr('transform', t0 + strTranslate(dx, dy));
23071
23082
 
23072
- xf = dragElement.align(opts._xLeftFrac + (dx / gs.w), opts._thickFrac,
23083
+ xf = dragElement.align(opts._uFrac + (dx / gs.w), opts._thickFrac,
23073
23084
  0, 1, opts.xanchor);
23074
- yf = dragElement.align(opts._yBottomFrac - (dy / gs.h), opts._lenFrac,
23085
+ yf = dragElement.align(opts._vFrac - (dy / gs.h), opts._lenFrac,
23075
23086
  0, 1, opts.yanchor);
23076
23087
 
23077
23088
  var csr = dragElement.getCursor(xf, yf, opts.xanchor, opts.yanchor);
@@ -25650,7 +25661,7 @@ var TEXTOFFSETSIGN = {
25650
25661
  start: 1, end: -1, middle: 0, bottom: 1, top: -1
25651
25662
  };
25652
25663
 
25653
- function textPointPosition(s, textPosition, fontSize, markerRadius) {
25664
+ function textPointPosition(s, textPosition, fontSize, markerRadius, dontTouchParent) {
25654
25665
  var group = d3.select(s.node().parentNode);
25655
25666
 
25656
25667
  var v = textPosition.indexOf('top') !== -1 ?
@@ -25672,7 +25683,9 @@ function textPointPosition(s, textPosition, fontSize, markerRadius) {
25672
25683
 
25673
25684
  // fix the overall text group position
25674
25685
  s.attr('text-anchor', h);
25675
- group.attr('transform', strTranslate(dx, dy));
25686
+ if(!dontTouchParent) {
25687
+ group.attr('transform', strTranslate(dx, dy));
25688
+ }
25676
25689
  }
25677
25690
 
25678
25691
  function extracTextFontSize(d, trace) {
@@ -25742,7 +25755,8 @@ drawing.selectedTextStyle = function(s, trace) {
25742
25755
  var fontSize = extracTextFontSize(d, trace);
25743
25756
 
25744
25757
  Color.fill(tx, tc);
25745
- textPointPosition(tx, tp, fontSize, d.mrc2 || d.mrc);
25758
+ var dontTouchParent = Registry.traceIs(trace, 'bar-like');
25759
+ textPointPosition(tx, tp, fontSize, d.mrc2 || d.mrc, dontTouchParent);
25746
25760
  });
25747
25761
  };
25748
25762
 
@@ -27773,11 +27787,13 @@ var cartesianScatterPoints = {
27773
27787
  // The actual rendering is done by private function _hover.
27774
27788
  exports.hover = function hover(gd, evt, subplot, noHoverEvent) {
27775
27789
  gd = Lib.getGraphDiv(gd);
27776
-
27790
+ // The 'target' property changes when bubbling out of Shadow DOM.
27791
+ // Throttling can delay reading the target, so we save the current value.
27792
+ var eventTarget = evt.target;
27777
27793
  Lib.throttle(
27778
27794
  gd._fullLayout._uid + constants.HOVERID,
27779
27795
  constants.HOVERMINTIME,
27780
- function() { _hover(gd, evt, subplot, noHoverEvent); }
27796
+ function() { _hover(gd, evt, subplot, noHoverEvent, eventTarget); }
27781
27797
  );
27782
27798
  };
27783
27799
 
@@ -27942,7 +27958,7 @@ exports.loneHover = function loneHover(hoverItems, opts) {
27942
27958
  };
27943
27959
 
27944
27960
  // The actual implementation is here:
27945
- function _hover(gd, evt, subplot, noHoverEvent) {
27961
+ function _hover(gd, evt, subplot, noHoverEvent, eventTarget) {
27946
27962
  if(!subplot) subplot = 'xy';
27947
27963
 
27948
27964
  // if the user passed in an array of subplots,
@@ -28061,7 +28077,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
28061
28077
  // [x|y]px: the pixels (from top left) of the mouse location
28062
28078
  // on the currently selected plot area
28063
28079
  // add pointerX|Y property for drawing the spikes in spikesnap 'cursor' situation
28064
- var hasUserCalledHover = !evt.target;
28080
+ var hasUserCalledHover = !eventTarget;
28065
28081
  var xpx, ypx;
28066
28082
 
28067
28083
  if(hasUserCalledHover) {
@@ -28078,13 +28094,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
28078
28094
  return;
28079
28095
  }
28080
28096
 
28081
- // Discover event target, traversing open shadow roots.
28082
- var target = evt.composedPath && evt.composedPath()[0];
28083
- if(!target) {
28084
- // Fallback for browsers not supporting composedPath
28085
- target = evt.target;
28086
- }
28087
- var dbb = target.getBoundingClientRect();
28097
+ var dbb = eventTarget.getBoundingClientRect();
28088
28098
 
28089
28099
  xpx = evt.clientX - dbb.left;
28090
28100
  ypx = evt.clientY - dbb.top;
@@ -28532,15 +28542,15 @@ function _hover(gd, evt, subplot, noHoverEvent) {
28532
28542
  if(!helpers.isUnifiedHover(hovermode)) {
28533
28543
  hoverAvoidOverlaps(hoverLabels, rotateLabels ? 'xa' : 'ya', fullLayout);
28534
28544
  alignHoverText(hoverLabels, rotateLabels, fullLayout._invScaleX, fullLayout._invScaleY);
28535
- } // TODO: tagName hack is needed to appease geo.js's hack of using evt.target=true
28545
+ } // TODO: tagName hack is needed to appease geo.js's hack of using eventTarget=true
28536
28546
  // we should improve the "fx" API so other plots can use it without these hack.
28537
- if(evt.target && evt.target.tagName) {
28547
+ if(eventTarget && eventTarget.tagName) {
28538
28548
  var hasClickToShow = Registry.getComponentMethod('annotations', 'hasClickToShow')(gd, newhoverdata);
28539
- overrideCursor(d3.select(evt.target), hasClickToShow ? 'pointer' : '');
28549
+ overrideCursor(d3.select(eventTarget), hasClickToShow ? 'pointer' : '');
28540
28550
  }
28541
28551
 
28542
28552
  // don't emit events if called manually
28543
- if(!evt.target || noHoverEvent || !hoverChanged(gd, evt, oldhoverdata)) return;
28553
+ if(!eventTarget || noHoverEvent || !hoverChanged(gd, evt, oldhoverdata)) return;
28544
28554
 
28545
28555
  if(oldhoverdata) {
28546
28556
  gd.emit('plotly_unhover', {
@@ -52023,7 +52033,8 @@ function findUIPattern(key, patternSpecs) {
52023
52033
  var spec = patternSpecs[i];
52024
52034
  var match = key.match(spec.pattern);
52025
52035
  if(match) {
52026
- return {head: match[1], attr: spec.attr};
52036
+ var head = match[1] || '';
52037
+ return {head: head, tail: key.substr(head.length + 1), attr: spec.attr};
52027
52038
  }
52028
52039
  }
52029
52040
  }
@@ -52075,26 +52086,54 @@ function valsMatch(v1, v2) {
52075
52086
 
52076
52087
  function applyUIRevisions(data, layout, oldFullData, oldFullLayout) {
52077
52088
  var layoutPreGUI = oldFullLayout._preGUI;
52078
- var key, revAttr, oldRev, newRev, match, preGUIVal, newNP, newVal;
52089
+ var key, revAttr, oldRev, newRev, match, preGUIVal, newNP, newVal, head, tail;
52079
52090
  var bothInheritAutorange = [];
52091
+ var newAutorangeIn = {};
52080
52092
  var newRangeAccepted = {};
52081
52093
  for(key in layoutPreGUI) {
52082
52094
  match = findUIPattern(key, layoutUIControlPatterns);
52083
52095
  if(match) {
52084
- revAttr = match.attr || (match.head + '.uirevision');
52096
+ head = match.head;
52097
+ tail = match.tail;
52098
+ revAttr = match.attr || (head + '.uirevision');
52085
52099
  oldRev = nestedProperty(oldFullLayout, revAttr).get();
52086
52100
  newRev = oldRev && getNewRev(revAttr, layout);
52101
+
52087
52102
  if(newRev && (newRev === oldRev)) {
52088
52103
  preGUIVal = layoutPreGUI[key];
52089
52104
  if(preGUIVal === null) preGUIVal = undefined;
52090
52105
  newNP = nestedProperty(layout, key);
52091
52106
  newVal = newNP.get();
52107
+
52092
52108
  if(valsMatch(newVal, preGUIVal)) {
52093
- if(newVal === undefined && key.substr(key.length - 9) === 'autorange') {
52094
- bothInheritAutorange.push(key.substr(0, key.length - 10));
52109
+ if(newVal === undefined && tail === 'autorange') {
52110
+ bothInheritAutorange.push(head);
52095
52111
  }
52096
52112
  newNP.set(undefinedToNull(nestedProperty(oldFullLayout, key).get()));
52097
52113
  continue;
52114
+ } else if(tail === 'autorange' || tail.substr(0, 6) === 'range[') {
52115
+ // Special case for (auto)range since we push it back into the layout
52116
+ // so all null should be treated equivalently to autorange: true with any range
52117
+ var pre0 = layoutPreGUI[head + '.range[0]'];
52118
+ var pre1 = layoutPreGUI[head + '.range[1]'];
52119
+ var preAuto = layoutPreGUI[head + '.autorange'];
52120
+ if(preAuto || (preAuto === null && pre0 === null && pre1 === null)) {
52121
+ // Only read the input layout once and stash the result,
52122
+ // so we get it before we start modifying it
52123
+ if(!(head in newAutorangeIn)) {
52124
+ var newContainer = nestedProperty(layout, head).get();
52125
+ newAutorangeIn[head] = newContainer && (
52126
+ newContainer.autorange ||
52127
+ (newContainer.autorange !== false && (
52128
+ !newContainer.range || newContainer.range.length !== 2)
52129
+ )
52130
+ );
52131
+ }
52132
+ if(newAutorangeIn[head]) {
52133
+ newNP.set(undefinedToNull(nestedProperty(oldFullLayout, key).get()));
52134
+ continue;
52135
+ }
52136
+ }
52098
52137
  }
52099
52138
  }
52100
52139
  } else {
@@ -52105,12 +52144,12 @@ function applyUIRevisions(data, layout, oldFullData, oldFullLayout) {
52105
52144
  // so remove it from _preGUI for next time.
52106
52145
  delete layoutPreGUI[key];
52107
52146
 
52108
- if(key.substr(key.length - 8, 6) === 'range[') {
52109
- newRangeAccepted[key.substr(0, key.length - 9)] = 1;
52147
+ if(match && match.tail.substr(0, 6) === 'range[') {
52148
+ newRangeAccepted[match.head] = 1;
52110
52149
  }
52111
52150
  }
52112
52151
 
52113
- // Special logic for `autorange`, since it interacts with `range`:
52152
+ // More special logic for `autorange`, since it interacts with `range`:
52114
52153
  // If the new figure's matching `range` was kept, and `autorange`
52115
52154
  // wasn't supplied explicitly in either the original or the new figure,
52116
52155
  // we shouldn't alter that - but we may just have done that, so fix it.
@@ -85944,7 +85983,7 @@ function getSortFunc(opts, d2c) {
85944
85983
  'use strict';
85945
85984
 
85946
85985
  // package version injected by `npm run preprocess`
85947
- exports.version = '2.6.1';
85986
+ exports.version = '2.7.0';
85948
85987
 
85949
85988
  },{}],435:[function(_dereq_,module,exports){
85950
85989
  (function (global){(function (){