plotly.js 2.7.0 → 2.8.3

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 (54) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +3 -3
  3. package/dist/README.md +26 -26
  4. package/dist/plot-schema.json +898 -407
  5. package/dist/plotly-basic.js +497 -186
  6. package/dist/plotly-basic.min.js +4 -4
  7. package/dist/plotly-cartesian.js +907 -329
  8. package/dist/plotly-cartesian.min.js +3 -3
  9. package/dist/plotly-finance.js +500 -188
  10. package/dist/plotly-finance.min.js +4 -4
  11. package/dist/plotly-geo-assets.js +2 -2
  12. package/dist/plotly-geo.js +486 -184
  13. package/dist/plotly-geo.min.js +4 -4
  14. package/dist/plotly-gl2d.js +505 -187
  15. package/dist/plotly-gl2d.min.js +2 -2
  16. package/dist/plotly-gl3d.js +486 -184
  17. package/dist/plotly-gl3d.min.js +2 -2
  18. package/dist/plotly-mapbox.js +486 -184
  19. package/dist/plotly-mapbox.min.js +2 -2
  20. package/dist/plotly-strict.js +1125 -547
  21. package/dist/plotly-strict.min.js +3 -3
  22. package/dist/plotly-with-meta.js +1214 -609
  23. package/dist/plotly.js +1179 -601
  24. package/dist/plotly.min.js +10 -10
  25. package/package.json +4 -4
  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/fx/hover.js +5 -2
  30. package/src/components/fx/hoverlabel_defaults.js +4 -2
  31. package/src/components/fx/layout_attributes.js +14 -4
  32. package/src/components/fx/layout_defaults.js +2 -0
  33. package/src/components/legend/attributes.js +7 -0
  34. package/src/components/legend/defaults.js +24 -7
  35. package/src/components/titles/index.js +8 -2
  36. package/src/plot_api/plot_api.js +1 -1
  37. package/src/plots/font_attributes.js +3 -0
  38. package/src/plots/layout_attributes.js +1 -0
  39. package/src/plots/plots.js +7 -15
  40. package/src/traces/bar/plot.js +8 -1
  41. package/src/traces/contour/attributes.js +12 -0
  42. package/src/traces/contour/defaults.js +9 -1
  43. package/src/traces/heatmap/attributes.js +16 -0
  44. package/src/traces/heatmap/defaults.js +2 -0
  45. package/src/traces/heatmap/label_defaults.js +13 -0
  46. package/src/traces/heatmap/plot.js +205 -4
  47. package/src/traces/histogram/calc.js +3 -2
  48. package/src/traces/histogram2d/attributes.js +8 -0
  49. package/src/traces/histogram2d/defaults.js +4 -0
  50. package/src/traces/histogram2dcontour/attributes.js +3 -1
  51. package/src/traces/histogram2dcontour/defaults.js +8 -1
  52. package/src/traces/pie/calc.js +3 -1
  53. package/src/version.js +1 -1
  54. package/tasks/test_mock.js +1 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * plotly.js (geo) v2.7.0
2
+ * plotly.js (geo) v2.8.3
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
+ );
35791
35829
 
35792
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
35830
+ var topOrBottom = ['top', 'bottom'].indexOf(titleSide) !== -1;
35831
+
35832
+ if(isVertical && topOrBottom) {
35793
35833
  ax.title.side = titleSide;
35794
- ax.titlex = optsX + xpadFrac;
35795
- ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
35834
+ ax.titlex = optsX + xpad / gs.w;
35835
+ ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypad / gs.h : ypad / gs.h);
35836
+ }
35837
+
35838
+ if(!isVertical && !topOrBottom) {
35839
+ ax.title.side = titleSide;
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;
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;
35873
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,
@@ -41875,7 +42142,9 @@ function createHoverText(hoverData, opts) {
41875
42142
  orientation: 'v'
41876
42143
  }
41877
42144
  };
41878
- var mockLayoutOut = {};
42145
+ var mockLayoutOut = {
42146
+ font: font
42147
+ };
41879
42148
  legendSupplyDefaults(mockLayoutIn, mockLayoutOut, gd._fullData);
41880
42149
  var mockLegend = mockLayoutOut.legend;
41881
42150
 
@@ -41916,7 +42185,8 @@ function createHoverText(hoverData, opts) {
41916
42185
 
41917
42186
  // Draw unified hover label
41918
42187
  mockLegend._inHover = true;
41919
- mockLegend._groupTitleFont = font;
42188
+ mockLegend._groupTitleFont = hoverlabel.grouptitlefont;
42189
+
41920
42190
  legendDraw(gd, mockLegend);
41921
42191
 
41922
42192
  // Position the hover
@@ -42918,9 +43188,11 @@ var isUnifiedHover = _dereq_('./helpers').isUnifiedHover;
42918
43188
  module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts) {
42919
43189
  opts = opts || {};
42920
43190
 
43191
+ var hasLegend = contOut.legend;
43192
+
42921
43193
  function inheritFontAttr(attr) {
42922
43194
  if(!opts.font[attr]) {
42923
- opts.font[attr] = contOut.legend ? contOut.legend.font[attr] : contOut.font[attr];
43195
+ opts.font[attr] = hasLegend ? contOut.legend.font[attr] : contOut.font[attr];
42924
43196
  }
42925
43197
  }
42926
43198
 
@@ -42931,7 +43203,7 @@ module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts
42931
43203
  inheritFontAttr('family');
42932
43204
  inheritFontAttr('color');
42933
43205
 
42934
- if(contOut.legend) {
43206
+ if(hasLegend) {
42935
43207
  if(!opts.bgcolor) opts.bgcolor = Color.combine(contOut.legend.bgcolor, contOut.paper_bgcolor);
42936
43208
  if(!opts.bordercolor) opts.bordercolor = contOut.legend.bordercolor;
42937
43209
  } else {
@@ -43040,11 +43312,13 @@ function castHoverinfo(trace, fullLayout, ptNumber) {
43040
43312
 
43041
43313
  var constants = _dereq_('./constants');
43042
43314
 
43043
- var fontAttrs = _dereq_('../../plots/font_attributes')({
43315
+ var fontAttrs = _dereq_('../../plots/font_attributes');
43316
+
43317
+ var font = fontAttrs({
43044
43318
  editType: 'none',
43045
43319
  });
43046
- fontAttrs.family.dflt = constants.HOVERFONT;
43047
- fontAttrs.size.dflt = constants.HOVERFONTSIZE;
43320
+ font.family.dflt = constants.HOVERFONT;
43321
+ font.size.dflt = constants.HOVERFONTSIZE;
43048
43322
 
43049
43323
  module.exports = {
43050
43324
  clickmode: {
@@ -43100,7 +43374,10 @@ module.exports = {
43100
43374
  valType: 'color',
43101
43375
  editType: 'none',
43102
43376
  },
43103
- font: fontAttrs,
43377
+ font: font,
43378
+ grouptitlefont: fontAttrs({
43379
+ editType: 'none',
43380
+ }),
43104
43381
  align: {
43105
43382
  valType: 'enumerated',
43106
43383
  values: ['left', 'right', 'auto'],
@@ -43113,6 +43390,7 @@ module.exports = {
43113
43390
  dflt: 15,
43114
43391
  editType: 'none',
43115
43392
  },
43393
+
43116
43394
  editType: 'none'
43117
43395
  },
43118
43396
  selectdirection: {
@@ -43160,6 +43438,8 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut) {
43160
43438
  }
43161
43439
 
43162
43440
  handleHoverLabelDefaults(layoutIn, layoutOut, coerce);
43441
+
43442
+ Lib.coerceFont(coerce, 'hoverlabel.grouptitlefont', layoutOut.hoverlabel.font);
43163
43443
  };
43164
43444
 
43165
43445
  },{"../../lib":248,"./hoverlabel_defaults":154,"./hovermode_defaults":155,"./layout_attributes":157}],159:[function(_dereq_,module,exports){
@@ -44043,6 +44323,9 @@ module.exports = {
44043
44323
  font: fontAttrs({
44044
44324
  editType: 'legend',
44045
44325
  }),
44326
+ grouptitlefont: fontAttrs({
44327
+ editType: 'legend',
44328
+ }),
44046
44329
  orientation: {
44047
44330
  valType: 'enumerated',
44048
44331
  values: ['v', 'h'],
@@ -44166,6 +44449,7 @@ var Registry = _dereq_('../../registry');
44166
44449
  var Lib = _dereq_('../../lib');
44167
44450
  var Template = _dereq_('../../plot_api/plot_template');
44168
44451
 
44452
+ var plotsAttrs = _dereq_('../../plots/attributes');
44169
44453
  var attributes = _dereq_('./attributes');
44170
44454
  var basePlotLayoutAttributes = _dereq_('../../plots/layout_attributes');
44171
44455
  var helpers = _dereq_('./helpers');
@@ -44173,13 +44457,30 @@ var helpers = _dereq_('./helpers');
44173
44457
 
44174
44458
  module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
44175
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
+ }));
44176
44477
 
44177
44478
  var legendTraceCount = 0;
44178
44479
  var legendReallyHasATrace = false;
44179
44480
  var defaultOrder = 'normal';
44180
44481
 
44181
44482
  for(var i = 0; i < fullData.length; i++) {
44182
- var trace = fullData[i];
44483
+ trace = fullData[i];
44183
44484
 
44184
44485
  if(!trace.visible) continue;
44185
44486
 
@@ -44206,6 +44507,8 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
44206
44507
  legendTraceCount++;
44207
44508
  }
44208
44509
  }
44510
+
44511
+ Lib.coerceFont(traceCoerce, 'legendgrouptitle.font', grouptitlefont);
44209
44512
  }
44210
44513
 
44211
44514
  if((Registry.traceIs(trace, 'bar') && layoutOut.barmode === 'stack') ||
@@ -44224,13 +44527,10 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
44224
44527
  basePlotLayoutAttributes, 'showlegend',
44225
44528
  legendReallyHasATrace && legendTraceCount > 1);
44226
44529
 
44227
- if(showLegend === false && !containerIn.uirevision) return;
44228
-
44229
- var containerOut = Template.newContainer(layoutOut, 'legend');
44530
+ // delete legend
44531
+ if(showLegend === false) layoutOut.legend = undefined;
44230
44532
 
44231
- function coerce(attr, dflt) {
44232
- return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
44233
- }
44533
+ if(showLegend === false && !containerIn.uirevision) return;
44234
44534
 
44235
44535
  coerce('uirevision', layoutOut.uirevision);
44236
44536
 
@@ -44292,7 +44592,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
44292
44592
  }
44293
44593
  };
44294
44594
 
44295
- },{"../../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){
44296
44596
  'use strict';
44297
44597
 
44298
44598
  var d3 = _dereq_('@plotly/d3');
@@ -52744,8 +53044,10 @@ function draw(gd, titleClass, options) {
52744
53044
 
52745
53045
  var elShouldExist = txt || editable;
52746
53046
 
53047
+ var hColorbarMoveTitle;
52747
53048
  if(!group) {
52748
53049
  group = Lib.ensureSingle(fullLayout._infolayer, 'g', 'g-' + titleClass);
53050
+ hColorbarMoveTitle = fullLayout._hColorbarMoveTitle;
52749
53051
  }
52750
53052
 
52751
53053
  var el = group.selectAll('text')
@@ -52769,13 +53071,17 @@ function draw(gd, titleClass, options) {
52769
53071
  function drawTitle(titleEl) {
52770
53072
  var transformVal;
52771
53073
 
53074
+ if(!transform && hColorbarMoveTitle) {
53075
+ transform = {};
53076
+ }
53077
+
52772
53078
  if(transform) {
52773
53079
  transformVal = '';
52774
53080
  if(transform.rotate) {
52775
53081
  transformVal += 'rotate(' + [transform.rotate, attributes.x, attributes.y] + ')';
52776
53082
  }
52777
- if(transform.offset) {
52778
- transformVal += strTranslate(0, transform.offset);
53083
+ if(transform.offset || hColorbarMoveTitle) {
53084
+ transformVal += strTranslate(0, (transform.offset || 0) - (hColorbarMoveTitle || 0));
52779
53085
  }
52780
53086
  } else {
52781
53087
  transformVal = null;
@@ -64744,7 +65050,7 @@ function cleanDeprecatedAttributeKeys(aobj) {
64744
65050
  if((key === 'title' || oldAxisTitleRegex.test(key) || colorbarRegex.test(key)) &&
64745
65051
  (typeof value === 'string' || typeof value === 'number')) {
64746
65052
  replace(key, key.replace('title', 'title.text'));
64747
- } else if(key.indexOf('titlefont') > -1) {
65053
+ } else if(key.indexOf('titlefont') > -1 && key.indexOf('grouptitlefont') === -1) {
64748
65054
  replace(key, key.replace('titlefont', 'title.font'));
64749
65055
  } else if(key.indexOf('titleposition') > -1) {
64750
65056
  replace(key, key.replace('titleposition', 'title.position'));
@@ -82612,6 +82918,9 @@ module.exports = function(opts) {
82612
82918
  // TODO - that's uber hacky... better solution?
82613
82919
  };
82614
82920
 
82921
+ if(opts.autoSize) attrs.size.dflt = 'auto';
82922
+ if(opts.autoColor) attrs.color.dflt = 'auto';
82923
+
82615
82924
  if(opts.arrayOk) {
82616
82925
  attrs.family.arrayOk = true;
82617
82926
  attrs.size.arrayOk = true;
@@ -85040,6 +85349,7 @@ module.exports = {
85040
85349
  valType: 'boolean',
85041
85350
  editType: 'legend',
85042
85351
  },
85352
+
85043
85353
  colorway: {
85044
85354
  valType: 'colorlist',
85045
85355
  dflt: colorAttrs.defaults,
@@ -86452,13 +86762,7 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac
86452
86762
  );
86453
86763
 
86454
86764
  coerce('legendgroup');
86455
- var titleText = coerce('legendgrouptitle.text');
86456
- if(titleText) {
86457
- Lib.coerceFont(coerce, 'legendgrouptitle.font', Lib.extendFlat({}, layout.font, {
86458
- size: Math.round(layout.font.size * 1.1) // default to larger font size
86459
- }));
86460
- }
86461
-
86765
+ coerce('legendgrouptitle.text');
86462
86766
  coerce('legendrank');
86463
86767
 
86464
86768
  traceOut._dfltShowLegend = true;
@@ -86606,16 +86910,14 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut, formatObj) {
86606
86910
 
86607
86911
  coerce('autotypenumbers');
86608
86912
 
86609
- var globalFont = Lib.coerceFont(coerce, 'font');
86610
-
86611
- coerce('title.text', layoutOut._dfltTitle.plot);
86913
+ var font = Lib.coerceFont(coerce, 'font');
86914
+ var fontSize = font.size;
86612
86915
 
86613
- Lib.coerceFont(coerce, 'title.font', {
86614
- family: globalFont.family,
86615
- size: Math.round(globalFont.size * 1.4),
86616
- color: globalFont.color
86617
- });
86916
+ Lib.coerceFont(coerce, 'title.font', Lib.extendFlat({}, font, {
86917
+ size: Math.round(fontSize * 1.4)
86918
+ }));
86618
86919
 
86920
+ coerce('title.text', layoutOut._dfltTitle.plot);
86619
86921
  coerce('title.xref');
86620
86922
  coerce('title.yref');
86621
86923
  coerce('title.x');
@@ -95076,7 +95378,7 @@ function getSortFunc(opts, d2c) {
95076
95378
  'use strict';
95077
95379
 
95078
95380
  // package version injected by `npm run preprocess`
95079
- exports.version = '2.7.0';
95381
+ exports.version = '2.8.3';
95080
95382
 
95081
95383
  },{}]},{},[8])(8)
95082
95384
  });