plotly.js 2.6.3 → 2.8.1

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +3 -3
  3. package/dist/README.md +26 -26
  4. package/dist/plot-schema.json +1015 -407
  5. package/dist/plotly-basic.js +533 -197
  6. package/dist/plotly-basic.min.js +4 -4
  7. package/dist/plotly-cartesian.js +996 -343
  8. package/dist/plotly-cartesian.min.js +3 -3
  9. package/dist/plotly-finance.js +583 -199
  10. package/dist/plotly-finance.min.js +4 -4
  11. package/dist/plotly-geo-assets.js +2 -2
  12. package/dist/plotly-geo.js +529 -195
  13. package/dist/plotly-geo.min.js +4 -4
  14. package/dist/plotly-gl2d.js +545 -196
  15. package/dist/plotly-gl2d.min.js +2 -2
  16. package/dist/plotly-gl3d.js +529 -195
  17. package/dist/plotly-gl3d.min.js +8 -8
  18. package/dist/plotly-mapbox.js +535 -198
  19. package/dist/plotly-mapbox.min.js +2 -2
  20. package/dist/plotly-strict.js +1220 -564
  21. package/dist/plotly-strict.min.js +3 -3
  22. package/dist/plotly-with-meta.js +1312 -626
  23. package/dist/plotly.js +1274 -618
  24. package/dist/plotly.min.js +10 -10
  25. package/package.json +9 -9
  26. package/src/components/colorbar/attributes.js +29 -20
  27. package/src/components/colorbar/defaults.js +30 -8
  28. package/src/components/colorbar/draw.js +374 -128
  29. package/src/components/drawing/index.js +6 -3
  30. package/src/components/fx/hover.js +5 -2
  31. package/src/components/fx/hoverlabel_defaults.js +4 -2
  32. package/src/components/fx/layout_attributes.js +14 -4
  33. package/src/components/fx/layout_defaults.js +2 -0
  34. package/src/components/legend/attributes.js +7 -0
  35. package/src/components/legend/defaults.js +24 -7
  36. package/src/components/titles/index.js +8 -2
  37. package/src/plot_api/plot_api.js +38 -9
  38. package/src/plots/font_attributes.js +3 -0
  39. package/src/plots/layout_attributes.js +1 -0
  40. package/src/plots/mapbox/mapbox.js +6 -3
  41. package/src/plots/plots.js +7 -15
  42. package/src/traces/bar/plot.js +1 -1
  43. package/src/traces/contour/attributes.js +12 -0
  44. package/src/traces/contour/defaults.js +9 -1
  45. package/src/traces/heatmap/attributes.js +16 -0
  46. package/src/traces/heatmap/defaults.js +2 -0
  47. package/src/traces/heatmap/label_defaults.js +13 -0
  48. package/src/traces/heatmap/plot.js +205 -4
  49. package/src/traces/histogram/attributes.js +40 -0
  50. package/src/traces/histogram/defaults.js +11 -0
  51. package/src/traces/histogram2d/attributes.js +8 -0
  52. package/src/traces/histogram2d/defaults.js +4 -0
  53. package/src/traces/histogram2dcontour/attributes.js +3 -1
  54. package/src/traces/histogram2dcontour/defaults.js +8 -1
  55. package/src/traces/pie/calc.js +3 -1
  56. package/src/version.js +1 -1
  57. package/tasks/test_mock.js +1 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * plotly.js (geo) v2.6.3
2
+ * plotly.js (geo) v2.8.1
3
3
  * Copyright 2012-2021, Plotly, Inc.
4
4
  * All rights reserved.
5
5
  * Licensed under the MIT license
@@ -35317,13 +35317,11 @@ var overrideAll = _dereq_('../../plot_api/edit_types').overrideAll;
35317
35317
 
35318
35318
 
35319
35319
  module.exports = overrideAll({
35320
- // TODO: only right is supported currently
35321
- // orient: {
35322
- // valType: 'enumerated',
35323
- // values: ['left', 'right', 'top', 'bottom'],
35324
- // dflt: 'right',
35325
- //
35326
- // },
35320
+ orientation: {
35321
+ valType: 'enumerated',
35322
+ values: ['h', 'v'],
35323
+ dflt: 'v',
35324
+ },
35327
35325
  thicknessmode: {
35328
35326
  valType: 'enumerated',
35329
35327
  values: ['fraction', 'pixels'],
@@ -35346,14 +35344,12 @@ module.exports = overrideAll({
35346
35344
  },
35347
35345
  x: {
35348
35346
  valType: 'number',
35349
- dflt: 1.02,
35350
35347
  min: -2,
35351
35348
  max: 3,
35352
35349
  },
35353
35350
  xanchor: {
35354
35351
  valType: 'enumerated',
35355
35352
  values: ['left', 'center', 'right'],
35356
- dflt: 'left',
35357
35353
  },
35358
35354
  xpad: {
35359
35355
  valType: 'number',
@@ -35362,14 +35358,12 @@ module.exports = overrideAll({
35362
35358
  },
35363
35359
  y: {
35364
35360
  valType: 'number',
35365
- dflt: 0.5,
35366
35361
  min: -2,
35367
35362
  max: 3,
35368
35363
  },
35369
35364
  yanchor: {
35370
35365
  valType: 'enumerated',
35371
35366
  values: ['top', 'middle', 'bottom'],
35372
- dflt: 'middle',
35373
35367
  },
35374
35368
  ypad: {
35375
35369
  valType: 'number',
@@ -35401,15 +35395,21 @@ module.exports = overrideAll({
35401
35395
  ticks: extendFlat({}, axesAttrs.ticks, {dflt: ''}),
35402
35396
  ticklabeloverflow: extendFlat({}, axesAttrs.ticklabeloverflow, {
35403
35397
  }),
35398
+
35399
+ // ticklabelposition: not used directly, as values depend on orientation
35400
+ // left/right options are for x axes, and top/bottom options are for y axes
35404
35401
  ticklabelposition: {
35405
35402
  valType: 'enumerated',
35406
35403
  values: [
35407
35404
  'outside', 'inside',
35408
35405
  'outside top', 'inside top',
35406
+ 'outside left', 'inside left',
35407
+ 'outside right', 'inside right',
35409
35408
  'outside bottom', 'inside bottom'
35410
35409
  ],
35411
35410
  dflt: 'outside',
35412
35411
  },
35412
+
35413
35413
  ticklen: axesAttrs.ticklen,
35414
35414
  tickwidth: axesAttrs.tickwidth,
35415
35415
  tickcolor: axesAttrs.tickcolor,
@@ -35436,7 +35436,6 @@ module.exports = overrideAll({
35436
35436
  side: {
35437
35437
  valType: 'enumerated',
35438
35438
  values: ['right', 'top', 'bottom'],
35439
- dflt: 'top',
35440
35439
  }
35441
35440
  },
35442
35441
 
@@ -35495,23 +35494,30 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
35495
35494
  return Lib.coerce(colorbarIn, colorbarOut, attributes, attr, dflt);
35496
35495
  }
35497
35496
 
35497
+ var margin = layout.margin || {t: 0, b: 0, l: 0, r: 0};
35498
+ var w = layout.width - margin.l - margin.r;
35499
+ var h = layout.height - margin.t - margin.b;
35500
+
35501
+ var orientation = coerce('orientation');
35502
+ var isVertical = orientation === 'v';
35503
+
35498
35504
  var thicknessmode = coerce('thicknessmode');
35499
35505
  coerce('thickness', (thicknessmode === 'fraction') ?
35500
- 30 / (layout.width - layout.margin.l - layout.margin.r) :
35506
+ 30 / (isVertical ? w : h) :
35501
35507
  30
35502
35508
  );
35503
35509
 
35504
35510
  var lenmode = coerce('lenmode');
35505
35511
  coerce('len', (lenmode === 'fraction') ?
35506
35512
  1 :
35507
- layout.height - layout.margin.t - layout.margin.b
35513
+ isVertical ? h : w
35508
35514
  );
35509
35515
 
35510
- coerce('x');
35511
- coerce('xanchor');
35516
+ coerce('x', isVertical ? 1.02 : 0.5);
35517
+ coerce('xanchor', isVertical ? 'left' : 'center');
35512
35518
  coerce('xpad');
35513
- coerce('y');
35514
- coerce('yanchor');
35519
+ coerce('y', isVertical ? 0.5 : 1.02);
35520
+ coerce('yanchor', isVertical ? 'middle' : 'bottom');
35515
35521
  coerce('ypad');
35516
35522
  Lib.noneOrAll(colorbarIn, colorbarOut, ['x', 'y']);
35517
35523
 
@@ -35521,7 +35527,22 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
35521
35527
  coerce('borderwidth');
35522
35528
  coerce('bgcolor');
35523
35529
 
35524
- var ticklabelposition = coerce('ticklabelposition');
35530
+ var ticklabelposition = Lib.coerce(colorbarIn, colorbarOut, {
35531
+ ticklabelposition: {
35532
+ valType: 'enumerated',
35533
+ dflt: 'outside',
35534
+ values: isVertical ? [
35535
+ 'outside', 'inside',
35536
+ 'outside top', 'inside top',
35537
+ 'outside bottom', 'inside bottom'
35538
+ ] : [
35539
+ 'outside', 'inside',
35540
+ 'outside left', 'inside left',
35541
+ 'outside right', 'inside right'
35542
+ ]
35543
+ }
35544
+ }, 'ticklabelposition');
35545
+
35525
35546
  coerce('ticklabeloverflow', ticklabelposition.indexOf('inside') !== -1 ? 'hide past domain' : 'hide past div');
35526
35547
 
35527
35548
  handleTickValueDefaults(colorbarIn, colorbarOut, coerce, 'linear');
@@ -35543,7 +35564,7 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
35543
35564
  size: Lib.bigFont(tickFont.size)
35544
35565
  });
35545
35566
  Lib.coerceFont(coerce, 'title.font', dfltTitleFont);
35546
- coerce('title.side');
35567
+ coerce('title.side', isVertical ? 'top' : 'right');
35547
35568
  };
35548
35569
 
35549
35570
  },{"../../lib":248,"../../plot_api/plot_template":285,"../../plots/cartesian/prefix_suffix_defaults":315,"../../plots/cartesian/tick_label_defaults":320,"../../plots/cartesian/tick_mark_defaults":321,"../../plots/cartesian/tick_value_defaults":322,"./attributes":117}],120:[function(_dereq_,module,exports){
@@ -35716,18 +35737,20 @@ function makeColorBarData(gd) {
35716
35737
  }
35717
35738
 
35718
35739
  function drawColorBar(g, opts, gd) {
35740
+ var isVertical = opts.orientation === 'v';
35719
35741
  var len = opts.len;
35720
35742
  var lenmode = opts.lenmode;
35721
35743
  var thickness = opts.thickness;
35722
35744
  var thicknessmode = opts.thicknessmode;
35723
35745
  var outlinewidth = opts.outlinewidth;
35724
35746
  var borderwidth = opts.borderwidth;
35747
+ var bgcolor = opts.bgcolor;
35725
35748
  var xanchor = opts.xanchor;
35726
35749
  var yanchor = opts.yanchor;
35727
35750
  var xpad = opts.xpad;
35728
35751
  var ypad = opts.ypad;
35729
35752
  var optsX = opts.x;
35730
- var optsY = opts.y;
35753
+ var optsY = isVertical ? opts.y : 1 - opts.y;
35731
35754
 
35732
35755
  var fullLayout = gd._fullLayout;
35733
35756
  var gs = fullLayout._size;
@@ -35758,23 +35781,35 @@ function drawColorBar(g, opts, gd) {
35758
35781
  // when the colorbar itself is pushing the margins.
35759
35782
  // but then the fractional size is calculated based on the
35760
35783
  // actual graph size, so that the axes will size correctly.
35761
- var thickPx = Math.round(thickness * (thicknessmode === 'fraction' ? gs.w : 1));
35762
- var thickFrac = thickPx / gs.w;
35763
- var lenPx = Math.round(len * (lenmode === 'fraction' ? gs.h : 1));
35764
- var lenFrac = lenPx / gs.h;
35765
- var xpadFrac = xpad / gs.w;
35766
- var yExtraPx = (borderwidth + outlinewidth) / 2;
35767
- var ypadFrac = ypad / gs.h;
35784
+ var thickPx = Math.round(thickness * (thicknessmode === 'fraction' ? (isVertical ? gs.w : gs.h) : 1));
35785
+ var thickFrac = thickPx / (isVertical ? gs.w : gs.h);
35786
+ var lenPx = Math.round(len * (lenmode === 'fraction' ? (isVertical ? gs.h : gs.w) : 1));
35787
+ var lenFrac = lenPx / (isVertical ? gs.h : gs.w);
35768
35788
 
35769
35789
  // x positioning: do it initially just for left anchor,
35770
35790
  // then fix at the end (since we don't know the width yet)
35771
- var uPx = Math.round(optsX * gs.w + xpad);
35772
- // for dragging... this is getting a little muddled...
35773
- var uFrac = optsX - thickFrac * ({center: 0.5, right: 1}[xanchor] || 0);
35791
+ var uPx = Math.round(isVertical ?
35792
+ optsX * gs.w + xpad :
35793
+ optsY * gs.h + ypad
35794
+ );
35774
35795
 
35775
- // y positioning we can do correctly from the start
35776
- var vFrac = optsY + lenFrac * (({top: -0.5, bottom: 0.5}[yanchor] || 0) - 0.5);
35777
- var vPx = Math.round(gs.h * (1 - vFrac));
35796
+ var xRatio = {center: 0.5, right: 1}[xanchor] || 0;
35797
+ var yRatio = {top: 1, middle: 0.5}[yanchor] || 0;
35798
+
35799
+ // for dragging... this is getting a little muddled...
35800
+ var uFrac = isVertical ?
35801
+ optsX - xRatio * thickFrac :
35802
+ optsY - yRatio * thickFrac;
35803
+
35804
+ // y/x positioning (for v/h) we can do correctly from the start
35805
+ var vFrac = isVertical ?
35806
+ optsY - yRatio * lenFrac :
35807
+ optsX - xRatio * lenFrac;
35808
+
35809
+ var vPx = Math.round(isVertical ?
35810
+ gs.h * (1 - vFrac) :
35811
+ gs.w * vFrac
35812
+ );
35778
35813
 
35779
35814
  // stash a few things for makeEditable
35780
35815
  opts._lenFrac = lenFrac;
@@ -35787,12 +35822,23 @@ function drawColorBar(g, opts, gd) {
35787
35822
 
35788
35823
  // position can't go in through supplyDefaults
35789
35824
  // because that restricts it to [0,1]
35790
- ax.position = optsX + xpadFrac + thickFrac;
35825
+ ax.position = thickFrac + (isVertical ?
35826
+ optsX + xpad / gs.w :
35827
+ optsY + ypad / gs.h
35828
+ );
35829
+
35830
+ var topOrBottom = ['top', 'bottom'].indexOf(titleSide) !== -1;
35831
+
35832
+ if(isVertical && topOrBottom) {
35833
+ ax.title.side = titleSide;
35834
+ ax.titlex = optsX + xpad / gs.w;
35835
+ ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypad / gs.h : ypad / gs.h);
35836
+ }
35791
35837
 
35792
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
35838
+ if(!isVertical && !topOrBottom) {
35793
35839
  ax.title.side = titleSide;
35794
- ax.titlex = optsX + xpadFrac;
35795
- ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
35840
+ ax.titley = optsY + ypad / gs.h;
35841
+ ax.titlex = vFrac + xpad / gs.w; // right side
35796
35842
  }
35797
35843
 
35798
35844
  if(line.color && opts.tickmode === 'auto') {
@@ -35817,9 +35863,12 @@ function drawColorBar(g, opts, gd) {
35817
35863
 
35818
35864
  // set domain after init, because we may want to
35819
35865
  // allow it outside [0,1]
35820
- ax.domain = [
35821
- vFrac + ypadFrac,
35822
- vFrac + lenFrac - ypadFrac
35866
+ ax.domain = isVertical ? [
35867
+ vFrac + ypad / gs.h,
35868
+ vFrac + lenFrac - ypad / gs.h
35869
+ ] : [
35870
+ vFrac + xpad / gs.w,
35871
+ vFrac + lenFrac - xpad / gs.w
35823
35872
  ];
35824
35873
 
35825
35874
  ax.setScale();
@@ -35829,9 +35878,13 @@ function drawColorBar(g, opts, gd) {
35829
35878
  var titleCont = g.select('.' + cn.cbtitleunshift)
35830
35879
  .attr('transform', strTranslate(-Math.round(gs.l), -Math.round(gs.t)));
35831
35880
 
35881
+ var ticklabelposition = ax.ticklabelposition;
35882
+ var titleFontSize = ax.title.font.size;
35883
+
35832
35884
  var axLayer = g.select('.' + cn.cbaxis);
35833
35885
  var titleEl;
35834
35886
  var titleHeight = 0;
35887
+ var titleWidth = 0;
35835
35888
 
35836
35889
  function drawTitle(titleClass, titleOpts) {
35837
35890
  var dfltTitleOpts = {
@@ -35856,54 +35909,98 @@ function drawColorBar(g, opts, gd) {
35856
35909
  }
35857
35910
 
35858
35911
  function drawDummyTitle() {
35859
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
35860
- // draw the title so we know how much room it needs
35861
- // when we squish the axis. This one only applies to
35862
- // top or bottom titles, not right side.
35863
- var x = gs.l + (optsX + xpadFrac) * gs.w;
35864
- var fontSize = ax.title.font.size;
35865
- var y;
35912
+ // draw the title so we know how much room it needs
35913
+ // when we squish the axis.
35914
+ // On vertical colorbars this only applies to top or bottom titles, not right side.
35915
+ // On horizontal colorbars this only applies to right, etc.
35916
+
35917
+ if(
35918
+ (isVertical && topOrBottom) ||
35919
+ (!isVertical && !topOrBottom)
35920
+ ) {
35921
+ var x, y;
35866
35922
 
35867
35923
  if(titleSide === 'top') {
35868
- y = (1 - (vFrac + lenFrac - ypadFrac)) * gs.h +
35869
- gs.t + 3 + fontSize * 0.75;
35870
- } else {
35871
- y = (1 - (vFrac + ypadFrac)) * gs.h +
35872
- gs.t - 3 - fontSize * 0.25;
35924
+ x = xpad + gs.l + gs.w * optsX;
35925
+ y = ypad + gs.t + gs.h * (1 - vFrac - lenFrac) + 3 + titleFontSize * 0.75;
35873
35926
  }
35927
+
35928
+ if(titleSide === 'bottom') {
35929
+ x = xpad + gs.l + gs.w * optsX;
35930
+ y = ypad + gs.t + gs.h * (1 - vFrac) - 3 - titleFontSize * 0.25;
35931
+ }
35932
+
35933
+ if(titleSide === 'right') {
35934
+ y = ypad + gs.t + gs.h * optsY + 3 + titleFontSize * 0.75;
35935
+ x = xpad + gs.l + gs.w * vFrac;
35936
+ }
35937
+
35874
35938
  drawTitle(ax._id + 'title', {
35875
- attributes: {x: x, y: y, 'text-anchor': 'start'}
35939
+ attributes: {x: x, y: y, 'text-anchor': isVertical ? 'start' : 'middle'}
35876
35940
  });
35877
35941
  }
35878
35942
  }
35879
35943
 
35880
35944
  function drawCbTitle() {
35881
- if(['top', 'bottom'].indexOf(titleSide) === -1) {
35882
- var fontSize = ax.title.font.size;
35883
- var y = ax._offset + ax._length / 2;
35884
- var x = gs.l + (ax.position || 0) * gs.w + ((ax.side === 'right') ?
35885
- 10 + fontSize * ((ax.showticklabels ? 1 : 0.5)) :
35886
- -10 - fontSize * ((ax.showticklabels ? 0.5 : 0)));
35887
-
35888
- // the 'h' + is a hack to get around the fact that
35889
- // convertToTspans rotates any 'y...' class by 90 degrees.
35890
- // TODO: find a better way to control this.
35891
- drawTitle('h' + ax._id + 'title', {
35945
+ if(
35946
+ (isVertical && !topOrBottom) ||
35947
+ (!isVertical && topOrBottom)
35948
+ ) {
35949
+ var pos = ax.position || 0;
35950
+ var mid = ax._offset + ax._length / 2;
35951
+ var x, y;
35952
+
35953
+ if(titleSide === 'right') {
35954
+ y = mid;
35955
+ x = gs.l + gs.w * pos + 10 + titleFontSize * (
35956
+ ax.showticklabels ? 1 : 0.5
35957
+ );
35958
+ } else {
35959
+ x = mid;
35960
+
35961
+ if(titleSide === 'bottom') {
35962
+ y = gs.t + gs.h * pos + 10 + (
35963
+ ticklabelposition.indexOf('inside') === -1 ?
35964
+ ax.tickfont.size :
35965
+ 0
35966
+ ) + (
35967
+ ax.ticks !== 'intside' ?
35968
+ opts.ticklen || 0 :
35969
+ 0
35970
+ );
35971
+ }
35972
+
35973
+ if(titleSide === 'top') {
35974
+ var nlines = title.text.split('<br>').length;
35975
+ y = gs.t + gs.h * pos + 10 - thickPx - LINE_SPACING * titleFontSize * nlines;
35976
+ }
35977
+ }
35978
+
35979
+ drawTitle((isVertical ?
35980
+ // the 'h' + is a hack to get around the fact that
35981
+ // convertToTspans rotates any 'y...' class by 90 degrees.
35982
+ // TODO: find a better way to control this.
35983
+ 'h' :
35984
+ 'v'
35985
+ ) + ax._id + 'title', {
35892
35986
  avoid: {
35893
35987
  selection: d3.select(gd).selectAll('g.' + ax._id + 'tick'),
35894
35988
  side: titleSide,
35895
- offsetLeft: gs.l,
35896
- offsetTop: 0,
35897
- maxShift: fullLayout.width
35989
+ offsetTop: isVertical ? 0 : gs.t,
35990
+ offsetLeft: isVertical ? gs.l : 0,
35991
+ maxShift: isVertical ? fullLayout.width : fullLayout.height
35898
35992
  },
35899
35993
  attributes: {x: x, y: y, 'text-anchor': 'middle'},
35900
- transform: {rotate: '-90', offset: 0}
35994
+ transform: {rotate: isVertical ? -90 : 0, offset: 0}
35901
35995
  });
35902
35996
  }
35903
35997
  }
35904
35998
 
35905
35999
  function drawAxis() {
35906
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
36000
+ if(
36001
+ (!isVertical && !topOrBottom) ||
36002
+ (isVertical && topOrBottom)
36003
+ ) {
35907
36004
  // squish the axis top to make room for the title
35908
36005
  var titleGroup = g.select('.' + cn.cbtitle);
35909
36006
  var titleText = titleGroup.select('text');
@@ -35915,39 +36012,63 @@ function drawColorBar(g, opts, gd) {
35915
36012
  if(titleText.node()) {
35916
36013
  lineSize = parseInt(titleText.node().style.fontSize, 10) * LINE_SPACING;
35917
36014
  }
36015
+
36016
+ var bb;
35918
36017
  if(mathJaxNode) {
35919
- titleHeight = Drawing.bBox(mathJaxNode).height;
36018
+ bb = Drawing.bBox(mathJaxNode);
36019
+ titleWidth = bb.width;
36020
+ titleHeight = bb.height;
35920
36021
  if(titleHeight > lineSize) {
35921
36022
  // not entirely sure how mathjax is doing
35922
36023
  // vertical alignment, but this seems to work.
35923
36024
  titleTrans[1] -= (titleHeight - lineSize) / 2;
35924
36025
  }
35925
36026
  } else if(titleText.node() && !titleText.classed(cn.jsPlaceholder)) {
35926
- titleHeight = Drawing.bBox(titleText.node()).height;
36027
+ bb = Drawing.bBox(titleText.node());
36028
+ titleWidth = bb.width;
36029
+ titleHeight = bb.height;
35927
36030
  }
35928
- if(titleHeight) {
35929
- // buffer btwn colorbar and title
35930
- // TODO: configurable
35931
- titleHeight += 5;
35932
36031
 
35933
- if(titleSide === 'top') {
35934
- ax.domain[1] -= titleHeight / gs.h;
35935
- titleTrans[1] *= -1;
35936
- } else {
35937
- ax.domain[0] += titleHeight / gs.h;
35938
- var nlines = svgTextUtils.lineCount(titleText);
35939
- titleTrans[1] += (1 - nlines) * lineSize;
36032
+ if(isVertical) {
36033
+ if(titleHeight) {
36034
+ // buffer btwn colorbar and title
36035
+ // TODO: configurable
36036
+ titleHeight += 5;
36037
+
36038
+ if(titleSide === 'top') {
36039
+ ax.domain[1] -= titleHeight / gs.h;
36040
+ titleTrans[1] *= -1;
36041
+ } else {
36042
+ ax.domain[0] += titleHeight / gs.h;
36043
+ var nlines = svgTextUtils.lineCount(titleText);
36044
+ titleTrans[1] += (1 - nlines) * lineSize;
36045
+ }
36046
+
36047
+ titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
36048
+ ax.setScale();
35940
36049
  }
36050
+ } else { // horizontal colorbars
36051
+ if(titleWidth) {
36052
+ if(titleSide === 'right') {
36053
+ ax.domain[0] += (titleWidth + titleFontSize / 2) / gs.w;
36054
+ }
35941
36055
 
35942
- titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
35943
- ax.setScale();
36056
+ titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
36057
+ ax.setScale();
36058
+ }
35944
36059
  }
35945
36060
  }
35946
36061
 
35947
36062
  g.selectAll('.' + cn.cbfills + ',.' + cn.cblines)
35948
- .attr('transform', strTranslate(0, Math.round(gs.h * (1 - ax.domain[1]))));
36063
+ .attr('transform', isVertical ?
36064
+ strTranslate(0, Math.round(gs.h * (1 - ax.domain[1]))) :
36065
+ strTranslate(Math.round(gs.w * ax.domain[0]), 0)
36066
+ );
35949
36067
 
35950
- axLayer.attr('transform', strTranslate(0, Math.round(-gs.t)));
36068
+ axLayer.attr('transform', isVertical ?
36069
+ strTranslate(0, Math.round(-gs.t)) :
36070
+ strTranslate(Math.round(-gs.l), 0)
36071
+ );
35951
36072
 
35952
36073
  var fills = g.select('.' + cn.cbfills)
35953
36074
  .selectAll('rect.' + cn.cbfill)
@@ -35973,20 +36094,22 @@ function drawColorBar(g, opts, gd) {
35973
36094
 
35974
36095
  // offset the side adjoining the next rectangle so they
35975
36096
  // overlap, to prevent antialiasing gaps
35976
- z[1] = Lib.constrain(z[1] + (z[1] > z[0]) ? 1 : -1, zBounds[0], zBounds[1]);
35977
-
36097
+ if(isVertical) {
36098
+ z[1] = Lib.constrain(z[1] + (z[1] > z[0]) ? 1 : -1, zBounds[0], zBounds[1]);
36099
+ } /* else {
36100
+ // TODO: horizontal case
36101
+ } */
35978
36102
 
35979
36103
  // Colorbar cannot currently support opacities so we
35980
36104
  // use an opaque fill even when alpha channels present
35981
- var fillEl = d3.select(this).attr({
35982
- x: uPx,
35983
- width: Math.max(thickPx, 2),
35984
- y: d3.min(z),
35985
- height: Math.max(d3.max(z) - d3.min(z), 2),
35986
- });
36105
+ var fillEl = d3.select(this)
36106
+ .attr(isVertical ? 'x' : 'y', uPx)
36107
+ .attr(isVertical ? 'y' : 'x', d3.min(z))
36108
+ .attr(isVertical ? 'width' : 'height', Math.max(thickPx, 2))
36109
+ .attr(isVertical ? 'height' : 'width', Math.max(d3.max(z) - d3.min(z), 2));
35987
36110
 
35988
36111
  if(opts._fillgradient) {
35989
- Drawing.gradient(fillEl, gd, opts._id, 'vertical', opts._fillgradient, 'fill');
36112
+ Drawing.gradient(fillEl, gd, opts._id, isVertical ? 'vertical' : 'horizontalreversed', opts._fillgradient, 'fill');
35990
36113
  } else {
35991
36114
  // tinycolor can't handle exponents and
35992
36115
  // at this scale, removing it makes no difference.
@@ -36002,9 +36125,15 @@ function drawColorBar(g, opts, gd) {
36002
36125
  .classed(cn.cbline, true);
36003
36126
  lines.exit().remove();
36004
36127
  lines.each(function(d) {
36128
+ var a = uPx;
36129
+ var b = (Math.round(ax.c2p(d)) + (line.width / 2) % 1);
36130
+
36005
36131
  d3.select(this)
36006
- .attr('d', 'M' + uPx + ',' +
36007
- (Math.round(ax.c2p(d)) + (line.width / 2) % 1) + 'h' + thickPx)
36132
+ .attr('d', 'M' +
36133
+ (isVertical ? a + ',' + b : b + ',' + a) +
36134
+ (isVertical ? 'h' : 'v') +
36135
+ thickPx
36136
+ )
36008
36137
  .call(Drawing.lineGroupStyle, line.width, lineColormap(d), line.dash);
36009
36138
  });
36010
36139
 
@@ -36037,82 +36166,211 @@ function drawColorBar(g, opts, gd) {
36037
36166
  // TODO: why are we redrawing multiple times now with this?
36038
36167
  // I guess autoMargin doesn't like being post-promise?
36039
36168
  function positionCB() {
36169
+ var bb;
36040
36170
  var innerThickness = thickPx + outlinewidth / 2;
36041
- if(ax.ticklabelposition.indexOf('inside') === -1) {
36042
- innerThickness += Drawing.bBox(axLayer.node()).width;
36171
+ if(ticklabelposition.indexOf('inside') === -1) {
36172
+ bb = Drawing.bBox(axLayer.node());
36173
+ innerThickness += isVertical ? bb.width : bb.height;
36043
36174
  }
36044
36175
 
36045
36176
  titleEl = titleCont.select('text');
36046
36177
 
36178
+ var titleWidth = 0;
36179
+
36180
+ var topSideVertical = isVertical && titleSide === 'top';
36181
+ var rightSideHorizontal = !isVertical && titleSide === 'right';
36182
+
36183
+ var moveY = 0;
36184
+
36047
36185
  if(titleEl.node() && !titleEl.classed(cn.jsPlaceholder)) {
36186
+ var _titleHeight;
36187
+
36048
36188
  var mathJaxNode = titleCont.select('.h' + ax._id + 'title-math-group').node();
36049
- var titleWidth;
36050
- if(mathJaxNode && ['top', 'bottom'].indexOf(titleSide) !== -1) {
36051
- titleWidth = Drawing.bBox(mathJaxNode).width;
36189
+ if(mathJaxNode && (
36190
+ (isVertical && topOrBottom) ||
36191
+ (!isVertical && !topOrBottom)
36192
+ )) {
36193
+ bb = Drawing.bBox(mathJaxNode);
36194
+ titleWidth = bb.width;
36195
+ _titleHeight = bb.height;
36052
36196
  } else {
36053
36197
  // note: the formula below works for all title sides,
36054
36198
  // (except for top/bottom mathjax, above)
36055
36199
  // but the weird gs.l is because the titleunshift
36056
36200
  // transform gets removed by Drawing.bBox
36057
- titleWidth = Drawing.bBox(titleCont.node()).right - uPx - gs.l;
36201
+ bb = Drawing.bBox(titleCont.node());
36202
+ titleWidth = bb.right - gs.l - (isVertical ? uPx : vPx);
36203
+ _titleHeight = bb.bottom - gs.t - (isVertical ? vPx : uPx);
36204
+
36205
+ if(
36206
+ !isVertical && titleSide === 'top'
36207
+ ) {
36208
+ innerThickness += bb.height;
36209
+ moveY = bb.height;
36210
+ }
36211
+ }
36212
+
36213
+ if(rightSideHorizontal) {
36214
+ titleEl.attr('transform', strTranslate(titleWidth / 2 + titleFontSize / 2, 0));
36215
+
36216
+ titleWidth *= 2;
36058
36217
  }
36059
- innerThickness = Math.max(innerThickness, titleWidth);
36218
+
36219
+ innerThickness = Math.max(innerThickness,
36220
+ isVertical ? titleWidth : _titleHeight
36221
+ );
36060
36222
  }
36061
36223
 
36062
- var outerThickness = 2 * xpad + innerThickness + borderwidth + outlinewidth / 2;
36224
+ var outerThickness = (isVertical ?
36225
+ xpad :
36226
+ ypad
36227
+ ) * 2 + innerThickness + borderwidth + outlinewidth / 2;
36063
36228
 
36064
- g.select('.' + cn.cbbg).attr({
36065
- x: uPx - xpad - (borderwidth + outlinewidth) / 2,
36066
- y: vPx - lenPx - yExtraPx,
36067
- width: Math.max(outerThickness, 2),
36068
- height: Math.max(lenPx + 2 * yExtraPx, 2)
36069
- })
36070
- .call(Color.fill, opts.bgcolor)
36229
+ var hColorbarMoveTitle = 0;
36230
+ if(!isVertical && title.text && yanchor === 'bottom' && optsY <= 0) {
36231
+ hColorbarMoveTitle = outerThickness / 2;
36232
+
36233
+ outerThickness += hColorbarMoveTitle;
36234
+ moveY += hColorbarMoveTitle;
36235
+ }
36236
+ fullLayout._hColorbarMoveTitle = hColorbarMoveTitle;
36237
+ fullLayout._hColorbarMoveCBTitle = moveY;
36238
+
36239
+ var extraW = borderwidth + outlinewidth;
36240
+
36241
+ g.select('.' + cn.cbbg)
36242
+ .attr('x', (isVertical ? uPx : vPx) - extraW / 2 - (isVertical ? xpad : 0))
36243
+ .attr('y', (isVertical ? vPx : uPx) - (isVertical ? lenPx : ypad + moveY - hColorbarMoveTitle))
36244
+ .attr(isVertical ? 'width' : 'height', Math.max(outerThickness - hColorbarMoveTitle, 2))
36245
+ .attr(isVertical ? 'height' : 'width', Math.max(lenPx + extraW, 2))
36246
+ .call(Color.fill, bgcolor)
36071
36247
  .call(Color.stroke, opts.bordercolor)
36072
36248
  .style('stroke-width', borderwidth);
36073
36249
 
36074
- g.selectAll('.' + cn.cboutline).attr({
36075
- x: uPx,
36076
- y: vPx - lenPx + ypad + (titleSide === 'top' ? titleHeight : 0),
36077
- width: Math.max(thickPx, 2),
36078
- height: Math.max(lenPx - 2 * ypad - titleHeight, 2)
36079
- })
36250
+ var moveX = rightSideHorizontal ? Math.max(titleWidth - 10, 0) : 0;
36251
+
36252
+ g.selectAll('.' + cn.cboutline)
36253
+ .attr('x', (isVertical ? uPx : vPx + xpad) + moveX)
36254
+ .attr('y', (isVertical ? vPx + ypad - lenPx : uPx) + (topSideVertical ? titleHeight : 0))
36255
+ .attr(isVertical ? 'width' : 'height', Math.max(thickPx, 2))
36256
+ .attr(isVertical ? 'height' : 'width', Math.max(lenPx - (isVertical ?
36257
+ 2 * ypad + titleHeight :
36258
+ 2 * xpad + moveX
36259
+ ), 2))
36080
36260
  .call(Color.stroke, opts.outlinecolor)
36081
36261
  .style({
36082
36262
  fill: 'none',
36083
36263
  'stroke-width': outlinewidth
36084
36264
  });
36085
36265
 
36086
- // fix positioning for xanchor!='left'
36087
- var xoffset = ({center: 0.5, right: 1}[xanchor] || 0) * outerThickness;
36088
- g.attr('transform', strTranslate(gs.l - xoffset, gs.t));
36266
+ g.attr('transform', strTranslate(
36267
+ gs.l - (isVertical ? xRatio * outerThickness : 0),
36268
+ gs.t - (isVertical ? 0 : (1 - yRatio) * outerThickness - moveY)
36269
+ ));
36270
+
36271
+ if(!isVertical && (
36272
+ borderwidth || (
36273
+ tinycolor(bgcolor).getAlpha() &&
36274
+ !tinycolor.equals(fullLayout.paper_bgcolor, bgcolor)
36275
+ )
36276
+ )) {
36277
+ // for horizontal colorbars when there is a border line or having different background color
36278
+ // hide/adjust x positioning for the first/last tick labels if they go outside the border
36279
+ var tickLabels = axLayer.selectAll('text');
36280
+ var numTicks = tickLabels[0].length;
36281
+
36282
+ var border = g.select('.' + cn.cbbg).node();
36283
+ var oBb = Drawing.bBox(border);
36284
+ var oTr = Drawing.getTranslate(g);
36285
+
36286
+ var TEXTPAD = 2;
36287
+
36288
+ tickLabels.each(function(d, i) {
36289
+ var first = 0;
36290
+ var last = numTicks - 1;
36291
+ if(i === first || i === last) {
36292
+ var iBb = Drawing.bBox(this);
36293
+ var iTr = Drawing.getTranslate(this);
36294
+ var deltaX;
36295
+
36296
+ if(i === last) {
36297
+ var iRight = iBb.right + iTr.x;
36298
+ var oRight = oBb.right + oTr.x + vPx - borderwidth - TEXTPAD + optsX;
36299
+
36300
+ deltaX = oRight - iRight;
36301
+ if(deltaX > 0) deltaX = 0;
36302
+ } else if(i === first) {
36303
+ var iLeft = iBb.left + iTr.x;
36304
+ var oLeft = oBb.left + oTr.x + vPx + borderwidth + TEXTPAD;
36305
+
36306
+ deltaX = oLeft - iLeft;
36307
+ if(deltaX < 0) deltaX = 0;
36308
+ }
36309
+
36310
+ if(deltaX) {
36311
+ if(numTicks < 3) { // adjust position
36312
+ this.setAttribute('transform',
36313
+ 'translate(' + deltaX + ',0) ' +
36314
+ this.getAttribute('transform')
36315
+ );
36316
+ } else { // hide
36317
+ this.setAttribute('visibility', 'hidden');
36318
+ }
36319
+ }
36320
+ }
36321
+ });
36322
+ }
36089
36323
 
36090
36324
  // auto margin adjustment
36091
36325
  var marginOpts = {};
36326
+ var lFrac = FROM_TL[xanchor];
36327
+ var rFrac = FROM_BR[xanchor];
36092
36328
  var tFrac = FROM_TL[yanchor];
36093
36329
  var bFrac = FROM_BR[yanchor];
36094
- if(lenmode === 'pixels') {
36095
- marginOpts.y = optsY;
36096
- marginOpts.t = lenPx * tFrac;
36097
- marginOpts.b = lenPx * bFrac;
36098
- } else {
36099
- marginOpts.t = marginOpts.b = 0;
36100
- marginOpts.yt = optsY + len * tFrac;
36101
- marginOpts.yb = optsY - len * bFrac;
36102
- }
36103
36330
 
36104
- var lFrac = FROM_TL[xanchor];
36105
- var rFrac = FROM_BR[xanchor];
36106
- if(thicknessmode === 'pixels') {
36107
- marginOpts.x = optsX;
36108
- marginOpts.l = outerThickness * lFrac;
36109
- marginOpts.r = outerThickness * rFrac;
36110
- } else {
36111
- var extraThickness = outerThickness - thickPx;
36112
- marginOpts.l = extraThickness * lFrac;
36113
- marginOpts.r = extraThickness * rFrac;
36114
- marginOpts.xl = optsX - thickness * lFrac;
36115
- marginOpts.xr = optsX + thickness * rFrac;
36331
+ var extraThickness = outerThickness - thickPx;
36332
+ if(isVertical) {
36333
+ if(lenmode === 'pixels') {
36334
+ marginOpts.y = optsY;
36335
+ marginOpts.t = lenPx * tFrac;
36336
+ marginOpts.b = lenPx * bFrac;
36337
+ } else {
36338
+ marginOpts.t = marginOpts.b = 0;
36339
+ marginOpts.yt = optsY + len * tFrac;
36340
+ marginOpts.yb = optsY - len * bFrac;
36341
+ }
36342
+
36343
+ if(thicknessmode === 'pixels') {
36344
+ marginOpts.x = optsX;
36345
+ marginOpts.l = outerThickness * lFrac;
36346
+ marginOpts.r = outerThickness * rFrac;
36347
+ } else {
36348
+ marginOpts.l = extraThickness * lFrac;
36349
+ marginOpts.r = extraThickness * rFrac;
36350
+ marginOpts.xl = optsX - thickness * lFrac;
36351
+ marginOpts.xr = optsX + thickness * rFrac;
36352
+ }
36353
+ } else { // horizontal colorbars
36354
+ if(lenmode === 'pixels') {
36355
+ marginOpts.x = optsX;
36356
+ marginOpts.l = lenPx * lFrac;
36357
+ marginOpts.r = lenPx * rFrac;
36358
+ } else {
36359
+ marginOpts.l = marginOpts.r = 0;
36360
+ marginOpts.xl = optsX + len * lFrac;
36361
+ marginOpts.xr = optsX - len * rFrac;
36362
+ }
36363
+
36364
+ if(thicknessmode === 'pixels') {
36365
+ marginOpts.y = 1 - optsY;
36366
+ marginOpts.t = outerThickness * tFrac;
36367
+ marginOpts.b = outerThickness * bFrac;
36368
+ } else {
36369
+ marginOpts.t = extraThickness * tFrac;
36370
+ marginOpts.b = extraThickness * bFrac;
36371
+ marginOpts.yt = optsY - thickness * tFrac;
36372
+ marginOpts.yb = optsY + thickness * bFrac;
36373
+ }
36116
36374
  }
36117
36375
 
36118
36376
  Plots.autoMargin(gd, opts._id, marginOpts);
@@ -36129,6 +36387,7 @@ function drawColorBar(g, opts, gd) {
36129
36387
  }
36130
36388
 
36131
36389
  function makeEditable(g, opts, gd) {
36390
+ var isVertical = opts.orientation === 'v';
36132
36391
  var fullLayout = gd._fullLayout;
36133
36392
  var gs = fullLayout._size;
36134
36393
  var t0, xf, yf;
@@ -36143,9 +36402,13 @@ function makeEditable(g, opts, gd) {
36143
36402
  moveFn: function(dx, dy) {
36144
36403
  g.attr('transform', t0 + strTranslate(dx, dy));
36145
36404
 
36146
- xf = dragElement.align(opts._uFrac + (dx / gs.w), opts._thickFrac,
36405
+ xf = dragElement.align(
36406
+ (isVertical ? opts._uFrac : opts._vFrac) + (dx / gs.w),
36407
+ isVertical ? opts._thickFrac : opts._lenFrac,
36147
36408
  0, 1, opts.xanchor);
36148
- yf = dragElement.align(opts._vFrac - (dy / gs.h), opts._lenFrac,
36409
+ yf = dragElement.align(
36410
+ (isVertical ? opts._vFrac : (1 - opts._uFrac)) - (dy / gs.h),
36411
+ isVertical ? opts._lenFrac : opts._thickFrac,
36149
36412
  0, 1, opts.yanchor);
36150
36413
 
36151
36414
  var csr = dragElement.getCursor(xf, yf, opts.xanchor, opts.yanchor);
@@ -36222,6 +36485,8 @@ function calcLevels(gd, opts, zrange) {
36222
36485
  function mockColorBarAxis(gd, opts, zrange) {
36223
36486
  var fullLayout = gd._fullLayout;
36224
36487
 
36488
+ var isVertical = opts.orientation === 'v';
36489
+
36225
36490
  var cbAxisIn = {
36226
36491
  type: 'linear',
36227
36492
  range: zrange,
@@ -36252,17 +36517,19 @@ function mockColorBarAxis(gd, opts, zrange) {
36252
36517
  title: opts.title,
36253
36518
  showline: true,
36254
36519
  anchor: 'free',
36255
- side: 'right',
36520
+ side: isVertical ? 'right' : 'bottom',
36256
36521
  position: 1
36257
36522
  };
36258
36523
 
36524
+ var letter = isVertical ? 'y' : 'x';
36525
+
36259
36526
  var cbAxisOut = {
36260
36527
  type: 'linear',
36261
- _id: 'y' + opts._id
36528
+ _id: letter + opts._id
36262
36529
  };
36263
36530
 
36264
36531
  var axisOptions = {
36265
- letter: 'y',
36532
+ letter: letter,
36266
36533
  font: fullLayout.font,
36267
36534
  noHover: true,
36268
36535
  noTickson: true,
@@ -38724,7 +38991,7 @@ var TEXTOFFSETSIGN = {
38724
38991
  start: 1, end: -1, middle: 0, bottom: 1, top: -1
38725
38992
  };
38726
38993
 
38727
- function textPointPosition(s, textPosition, fontSize, markerRadius) {
38994
+ function textPointPosition(s, textPosition, fontSize, markerRadius, dontTouchParent) {
38728
38995
  var group = d3.select(s.node().parentNode);
38729
38996
 
38730
38997
  var v = textPosition.indexOf('top') !== -1 ?
@@ -38746,7 +39013,9 @@ function textPointPosition(s, textPosition, fontSize, markerRadius) {
38746
39013
 
38747
39014
  // fix the overall text group position
38748
39015
  s.attr('text-anchor', h);
38749
- group.attr('transform', strTranslate(dx, dy));
39016
+ if(!dontTouchParent) {
39017
+ group.attr('transform', strTranslate(dx, dy));
39018
+ }
38750
39019
  }
38751
39020
 
38752
39021
  function extracTextFontSize(d, trace) {
@@ -38816,7 +39085,8 @@ drawing.selectedTextStyle = function(s, trace) {
38816
39085
  var fontSize = extracTextFontSize(d, trace);
38817
39086
 
38818
39087
  Color.fill(tx, tc);
38819
- textPointPosition(tx, tp, fontSize, d.mrc2 || d.mrc);
39088
+ var dontTouchParent = Registry.traceIs(trace, 'bar-like');
39089
+ textPointPosition(tx, tp, fontSize, d.mrc2 || d.mrc, dontTouchParent);
38820
39090
  });
38821
39091
  };
38822
39092
 
@@ -41872,7 +42142,9 @@ function createHoverText(hoverData, opts) {
41872
42142
  orientation: 'v'
41873
42143
  }
41874
42144
  };
41875
- var mockLayoutOut = {};
42145
+ var mockLayoutOut = {
42146
+ font: font
42147
+ };
41876
42148
  legendSupplyDefaults(mockLayoutIn, mockLayoutOut, gd._fullData);
41877
42149
  var mockLegend = mockLayoutOut.legend;
41878
42150
 
@@ -41913,7 +42185,8 @@ function createHoverText(hoverData, opts) {
41913
42185
 
41914
42186
  // Draw unified hover label
41915
42187
  mockLegend._inHover = true;
41916
- mockLegend._groupTitleFont = font;
42188
+ mockLegend._groupTitleFont = hoverlabel.grouptitlefont;
42189
+
41917
42190
  legendDraw(gd, mockLegend);
41918
42191
 
41919
42192
  // Position the hover
@@ -42915,9 +43188,11 @@ var isUnifiedHover = _dereq_('./helpers').isUnifiedHover;
42915
43188
  module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts) {
42916
43189
  opts = opts || {};
42917
43190
 
43191
+ var hasLegend = contOut.legend;
43192
+
42918
43193
  function inheritFontAttr(attr) {
42919
43194
  if(!opts.font[attr]) {
42920
- opts.font[attr] = contOut.legend ? contOut.legend.font[attr] : contOut.font[attr];
43195
+ opts.font[attr] = hasLegend ? contOut.legend.font[attr] : contOut.font[attr];
42921
43196
  }
42922
43197
  }
42923
43198
 
@@ -42928,7 +43203,7 @@ module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts
42928
43203
  inheritFontAttr('family');
42929
43204
  inheritFontAttr('color');
42930
43205
 
42931
- if(contOut.legend) {
43206
+ if(hasLegend) {
42932
43207
  if(!opts.bgcolor) opts.bgcolor = Color.combine(contOut.legend.bgcolor, contOut.paper_bgcolor);
42933
43208
  if(!opts.bordercolor) opts.bordercolor = contOut.legend.bordercolor;
42934
43209
  } else {
@@ -43037,11 +43312,13 @@ function castHoverinfo(trace, fullLayout, ptNumber) {
43037
43312
 
43038
43313
  var constants = _dereq_('./constants');
43039
43314
 
43040
- var fontAttrs = _dereq_('../../plots/font_attributes')({
43315
+ var fontAttrs = _dereq_('../../plots/font_attributes');
43316
+
43317
+ var font = fontAttrs({
43041
43318
  editType: 'none',
43042
43319
  });
43043
- fontAttrs.family.dflt = constants.HOVERFONT;
43044
- fontAttrs.size.dflt = constants.HOVERFONTSIZE;
43320
+ font.family.dflt = constants.HOVERFONT;
43321
+ font.size.dflt = constants.HOVERFONTSIZE;
43045
43322
 
43046
43323
  module.exports = {
43047
43324
  clickmode: {
@@ -43097,7 +43374,10 @@ module.exports = {
43097
43374
  valType: 'color',
43098
43375
  editType: 'none',
43099
43376
  },
43100
- font: fontAttrs,
43377
+ font: font,
43378
+ grouptitlefont: fontAttrs({
43379
+ editType: 'none',
43380
+ }),
43101
43381
  align: {
43102
43382
  valType: 'enumerated',
43103
43383
  values: ['left', 'right', 'auto'],
@@ -43110,6 +43390,7 @@ module.exports = {
43110
43390
  dflt: 15,
43111
43391
  editType: 'none',
43112
43392
  },
43393
+
43113
43394
  editType: 'none'
43114
43395
  },
43115
43396
  selectdirection: {
@@ -43157,6 +43438,8 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut) {
43157
43438
  }
43158
43439
 
43159
43440
  handleHoverLabelDefaults(layoutIn, layoutOut, coerce);
43441
+
43442
+ Lib.coerceFont(coerce, 'hoverlabel.grouptitlefont', layoutOut.hoverlabel.font);
43160
43443
  };
43161
43444
 
43162
43445
  },{"../../lib":248,"./hoverlabel_defaults":154,"./hovermode_defaults":155,"./layout_attributes":157}],159:[function(_dereq_,module,exports){
@@ -44040,6 +44323,9 @@ module.exports = {
44040
44323
  font: fontAttrs({
44041
44324
  editType: 'legend',
44042
44325
  }),
44326
+ grouptitlefont: fontAttrs({
44327
+ editType: 'legend',
44328
+ }),
44043
44329
  orientation: {
44044
44330
  valType: 'enumerated',
44045
44331
  values: ['v', 'h'],
@@ -44163,6 +44449,7 @@ var Registry = _dereq_('../../registry');
44163
44449
  var Lib = _dereq_('../../lib');
44164
44450
  var Template = _dereq_('../../plot_api/plot_template');
44165
44451
 
44452
+ var plotsAttrs = _dereq_('../../plots/attributes');
44166
44453
  var attributes = _dereq_('./attributes');
44167
44454
  var basePlotLayoutAttributes = _dereq_('../../plots/layout_attributes');
44168
44455
  var helpers = _dereq_('./helpers');
@@ -44170,13 +44457,30 @@ var helpers = _dereq_('./helpers');
44170
44457
 
44171
44458
  module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
44172
44459
  var containerIn = layoutIn.legend || {};
44460
+ var containerOut = Template.newContainer(layoutOut, 'legend');
44461
+
44462
+ function coerce(attr, dflt) {
44463
+ return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
44464
+ }
44465
+
44466
+ var trace;
44467
+ var traceCoerce = function(attr, dflt) {
44468
+ var traceIn = trace._input;
44469
+ var traceOut = trace;
44470
+ return Lib.coerce(traceIn, traceOut, plotsAttrs, attr, dflt);
44471
+ };
44472
+
44473
+ var globalFont = layoutOut.font || {};
44474
+ var grouptitlefont = Lib.coerceFont(coerce, 'grouptitlefont', Lib.extendFlat({}, globalFont, {
44475
+ size: Math.round(globalFont.size * 1.1)
44476
+ }));
44173
44477
 
44174
44478
  var legendTraceCount = 0;
44175
44479
  var legendReallyHasATrace = false;
44176
44480
  var defaultOrder = 'normal';
44177
44481
 
44178
44482
  for(var i = 0; i < fullData.length; i++) {
44179
- var trace = fullData[i];
44483
+ trace = fullData[i];
44180
44484
 
44181
44485
  if(!trace.visible) continue;
44182
44486
 
@@ -44203,6 +44507,8 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
44203
44507
  legendTraceCount++;
44204
44508
  }
44205
44509
  }
44510
+
44511
+ Lib.coerceFont(traceCoerce, 'legendgrouptitle.font', grouptitlefont);
44206
44512
  }
44207
44513
 
44208
44514
  if((Registry.traceIs(trace, 'bar') && layoutOut.barmode === 'stack') ||
@@ -44221,13 +44527,10 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
44221
44527
  basePlotLayoutAttributes, 'showlegend',
44222
44528
  legendReallyHasATrace && legendTraceCount > 1);
44223
44529
 
44224
- if(showLegend === false && !containerIn.uirevision) return;
44225
-
44226
- var containerOut = Template.newContainer(layoutOut, 'legend');
44530
+ // delete legend
44531
+ if(showLegend === false) layoutOut.legend = undefined;
44227
44532
 
44228
- function coerce(attr, dflt) {
44229
- return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
44230
- }
44533
+ if(showLegend === false && !containerIn.uirevision) return;
44231
44534
 
44232
44535
  coerce('uirevision', layoutOut.uirevision);
44233
44536
 
@@ -44289,7 +44592,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
44289
44592
  }
44290
44593
  };
44291
44594
 
44292
- },{"../../lib":248,"../../plot_api/plot_template":285,"../../plots/layout_attributes":337,"../../registry":342,"./attributes":166,"./helpers":172}],169:[function(_dereq_,module,exports){
44595
+ },{"../../lib":248,"../../plot_api/plot_template":285,"../../plots/attributes":292,"../../plots/layout_attributes":337,"../../registry":342,"./attributes":166,"./helpers":172}],169:[function(_dereq_,module,exports){
44293
44596
  'use strict';
44294
44597
 
44295
44598
  var d3 = _dereq_('@plotly/d3');
@@ -52741,8 +53044,10 @@ function draw(gd, titleClass, options) {
52741
53044
 
52742
53045
  var elShouldExist = txt || editable;
52743
53046
 
53047
+ var hColorbarMoveTitle;
52744
53048
  if(!group) {
52745
53049
  group = Lib.ensureSingle(fullLayout._infolayer, 'g', 'g-' + titleClass);
53050
+ hColorbarMoveTitle = fullLayout._hColorbarMoveTitle;
52746
53051
  }
52747
53052
 
52748
53053
  var el = group.selectAll('text')
@@ -52766,13 +53071,17 @@ function draw(gd, titleClass, options) {
52766
53071
  function drawTitle(titleEl) {
52767
53072
  var transformVal;
52768
53073
 
53074
+ if(!transform && hColorbarMoveTitle) {
53075
+ transform = {};
53076
+ }
53077
+
52769
53078
  if(transform) {
52770
53079
  transformVal = '';
52771
53080
  if(transform.rotate) {
52772
53081
  transformVal += 'rotate(' + [transform.rotate, attributes.x, attributes.y] + ')';
52773
53082
  }
52774
- if(transform.offset) {
52775
- transformVal += strTranslate(0, transform.offset);
53083
+ if(transform.offset || hColorbarMoveTitle) {
53084
+ transformVal += strTranslate(0, (transform.offset || 0) - (hColorbarMoveTitle || 0));
52776
53085
  }
52777
53086
  } else {
52778
53087
  transformVal = null;
@@ -64741,7 +65050,7 @@ function cleanDeprecatedAttributeKeys(aobj) {
64741
65050
  if((key === 'title' || oldAxisTitleRegex.test(key) || colorbarRegex.test(key)) &&
64742
65051
  (typeof value === 'string' || typeof value === 'number')) {
64743
65052
  replace(key, key.replace('title', 'title.text'));
64744
- } else if(key.indexOf('titlefont') > -1) {
65053
+ } else if(key.indexOf('titlefont') > -1 && key.indexOf('grouptitlefont') === -1) {
64745
65054
  replace(key, key.replace('titlefont', 'title.font'));
64746
65055
  } else if(key.indexOf('titleposition') > -1) {
64747
65056
  replace(key, key.replace('titleposition', 'title.position'));
@@ -65418,7 +65727,8 @@ function findUIPattern(key, patternSpecs) {
65418
65727
  var spec = patternSpecs[i];
65419
65728
  var match = key.match(spec.pattern);
65420
65729
  if(match) {
65421
- return {head: match[1], attr: spec.attr};
65730
+ var head = match[1] || '';
65731
+ return {head: head, tail: key.substr(head.length + 1), attr: spec.attr};
65422
65732
  }
65423
65733
  }
65424
65734
  }
@@ -65470,26 +65780,54 @@ function valsMatch(v1, v2) {
65470
65780
 
65471
65781
  function applyUIRevisions(data, layout, oldFullData, oldFullLayout) {
65472
65782
  var layoutPreGUI = oldFullLayout._preGUI;
65473
- var key, revAttr, oldRev, newRev, match, preGUIVal, newNP, newVal;
65783
+ var key, revAttr, oldRev, newRev, match, preGUIVal, newNP, newVal, head, tail;
65474
65784
  var bothInheritAutorange = [];
65785
+ var newAutorangeIn = {};
65475
65786
  var newRangeAccepted = {};
65476
65787
  for(key in layoutPreGUI) {
65477
65788
  match = findUIPattern(key, layoutUIControlPatterns);
65478
65789
  if(match) {
65479
- revAttr = match.attr || (match.head + '.uirevision');
65790
+ head = match.head;
65791
+ tail = match.tail;
65792
+ revAttr = match.attr || (head + '.uirevision');
65480
65793
  oldRev = nestedProperty(oldFullLayout, revAttr).get();
65481
65794
  newRev = oldRev && getNewRev(revAttr, layout);
65795
+
65482
65796
  if(newRev && (newRev === oldRev)) {
65483
65797
  preGUIVal = layoutPreGUI[key];
65484
65798
  if(preGUIVal === null) preGUIVal = undefined;
65485
65799
  newNP = nestedProperty(layout, key);
65486
65800
  newVal = newNP.get();
65801
+
65487
65802
  if(valsMatch(newVal, preGUIVal)) {
65488
- if(newVal === undefined && key.substr(key.length - 9) === 'autorange') {
65489
- bothInheritAutorange.push(key.substr(0, key.length - 10));
65803
+ if(newVal === undefined && tail === 'autorange') {
65804
+ bothInheritAutorange.push(head);
65490
65805
  }
65491
65806
  newNP.set(undefinedToNull(nestedProperty(oldFullLayout, key).get()));
65492
65807
  continue;
65808
+ } else if(tail === 'autorange' || tail.substr(0, 6) === 'range[') {
65809
+ // Special case for (auto)range since we push it back into the layout
65810
+ // so all null should be treated equivalently to autorange: true with any range
65811
+ var pre0 = layoutPreGUI[head + '.range[0]'];
65812
+ var pre1 = layoutPreGUI[head + '.range[1]'];
65813
+ var preAuto = layoutPreGUI[head + '.autorange'];
65814
+ if(preAuto || (preAuto === null && pre0 === null && pre1 === null)) {
65815
+ // Only read the input layout once and stash the result,
65816
+ // so we get it before we start modifying it
65817
+ if(!(head in newAutorangeIn)) {
65818
+ var newContainer = nestedProperty(layout, head).get();
65819
+ newAutorangeIn[head] = newContainer && (
65820
+ newContainer.autorange ||
65821
+ (newContainer.autorange !== false && (
65822
+ !newContainer.range || newContainer.range.length !== 2)
65823
+ )
65824
+ );
65825
+ }
65826
+ if(newAutorangeIn[head]) {
65827
+ newNP.set(undefinedToNull(nestedProperty(oldFullLayout, key).get()));
65828
+ continue;
65829
+ }
65830
+ }
65493
65831
  }
65494
65832
  }
65495
65833
  } else {
@@ -65500,12 +65838,12 @@ function applyUIRevisions(data, layout, oldFullData, oldFullLayout) {
65500
65838
  // so remove it from _preGUI for next time.
65501
65839
  delete layoutPreGUI[key];
65502
65840
 
65503
- if(key.substr(key.length - 8, 6) === 'range[') {
65504
- newRangeAccepted[key.substr(0, key.length - 9)] = 1;
65841
+ if(match && match.tail.substr(0, 6) === 'range[') {
65842
+ newRangeAccepted[match.head] = 1;
65505
65843
  }
65506
65844
  }
65507
65845
 
65508
- // Special logic for `autorange`, since it interacts with `range`:
65846
+ // More special logic for `autorange`, since it interacts with `range`:
65509
65847
  // If the new figure's matching `range` was kept, and `autorange`
65510
65848
  // wasn't supplied explicitly in either the original or the new figure,
65511
65849
  // we shouldn't alter that - but we may just have done that, so fix it.
@@ -82580,6 +82918,9 @@ module.exports = function(opts) {
82580
82918
  // TODO - that's uber hacky... better solution?
82581
82919
  };
82582
82920
 
82921
+ if(opts.autoSize) attrs.size.dflt = 'auto';
82922
+ if(opts.autoColor) attrs.color.dflt = 'auto';
82923
+
82583
82924
  if(opts.arrayOk) {
82584
82925
  attrs.family.arrayOk = true;
82585
82926
  attrs.size.arrayOk = true;
@@ -85008,6 +85349,7 @@ module.exports = {
85008
85349
  valType: 'boolean',
85009
85350
  editType: 'legend',
85010
85351
  },
85352
+
85011
85353
  colorway: {
85012
85354
  valType: 'colorlist',
85013
85355
  dflt: colorAttrs.defaults,
@@ -86420,13 +86762,7 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac
86420
86762
  );
86421
86763
 
86422
86764
  coerce('legendgroup');
86423
- var titleText = coerce('legendgrouptitle.text');
86424
- if(titleText) {
86425
- Lib.coerceFont(coerce, 'legendgrouptitle.font', Lib.extendFlat({}, layout.font, {
86426
- size: Math.round(layout.font.size * 1.1) // default to larger font size
86427
- }));
86428
- }
86429
-
86765
+ coerce('legendgrouptitle.text');
86430
86766
  coerce('legendrank');
86431
86767
 
86432
86768
  traceOut._dfltShowLegend = true;
@@ -86574,16 +86910,14 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut, formatObj) {
86574
86910
 
86575
86911
  coerce('autotypenumbers');
86576
86912
 
86577
- var globalFont = Lib.coerceFont(coerce, 'font');
86578
-
86579
- coerce('title.text', layoutOut._dfltTitle.plot);
86913
+ var font = Lib.coerceFont(coerce, 'font');
86914
+ var fontSize = font.size;
86580
86915
 
86581
- Lib.coerceFont(coerce, 'title.font', {
86582
- family: globalFont.family,
86583
- size: Math.round(globalFont.size * 1.4),
86584
- color: globalFont.color
86585
- });
86916
+ Lib.coerceFont(coerce, 'title.font', Lib.extendFlat({}, font, {
86917
+ size: Math.round(fontSize * 1.4)
86918
+ }));
86586
86919
 
86920
+ coerce('title.text', layoutOut._dfltTitle.plot);
86587
86921
  coerce('title.xref');
86588
86922
  coerce('title.yref');
86589
86923
  coerce('title.x');
@@ -95044,7 +95378,7 @@ function getSortFunc(opts, d2c) {
95044
95378
  'use strict';
95045
95379
 
95046
95380
  // package version injected by `npm run preprocess`
95047
- exports.version = '2.6.3';
95381
+ exports.version = '2.8.1';
95048
95382
 
95049
95383
  },{}]},{},[8])(8)
95050
95384
  });