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 (gl2d) v2.7.0
2
+ * plotly.js (gl2d) v2.8.3
3
3
  * Copyright 2012-2021, Plotly, Inc.
4
4
  * All rights reserved.
5
5
  * Licensed under the MIT license
@@ -35026,13 +35026,11 @@ var overrideAll = _dereq_('../../plot_api/edit_types').overrideAll;
35026
35026
 
35027
35027
 
35028
35028
  module.exports = overrideAll({
35029
- // TODO: only right is supported currently
35030
- // orient: {
35031
- // valType: 'enumerated',
35032
- // values: ['left', 'right', 'top', 'bottom'],
35033
- // dflt: 'right',
35034
- //
35035
- // },
35029
+ orientation: {
35030
+ valType: 'enumerated',
35031
+ values: ['h', 'v'],
35032
+ dflt: 'v',
35033
+ },
35036
35034
  thicknessmode: {
35037
35035
  valType: 'enumerated',
35038
35036
  values: ['fraction', 'pixels'],
@@ -35055,14 +35053,12 @@ module.exports = overrideAll({
35055
35053
  },
35056
35054
  x: {
35057
35055
  valType: 'number',
35058
- dflt: 1.02,
35059
35056
  min: -2,
35060
35057
  max: 3,
35061
35058
  },
35062
35059
  xanchor: {
35063
35060
  valType: 'enumerated',
35064
35061
  values: ['left', 'center', 'right'],
35065
- dflt: 'left',
35066
35062
  },
35067
35063
  xpad: {
35068
35064
  valType: 'number',
@@ -35071,14 +35067,12 @@ module.exports = overrideAll({
35071
35067
  },
35072
35068
  y: {
35073
35069
  valType: 'number',
35074
- dflt: 0.5,
35075
35070
  min: -2,
35076
35071
  max: 3,
35077
35072
  },
35078
35073
  yanchor: {
35079
35074
  valType: 'enumerated',
35080
35075
  values: ['top', 'middle', 'bottom'],
35081
- dflt: 'middle',
35082
35076
  },
35083
35077
  ypad: {
35084
35078
  valType: 'number',
@@ -35110,15 +35104,21 @@ module.exports = overrideAll({
35110
35104
  ticks: extendFlat({}, axesAttrs.ticks, {dflt: ''}),
35111
35105
  ticklabeloverflow: extendFlat({}, axesAttrs.ticklabeloverflow, {
35112
35106
  }),
35107
+
35108
+ // ticklabelposition: not used directly, as values depend on orientation
35109
+ // left/right options are for x axes, and top/bottom options are for y axes
35113
35110
  ticklabelposition: {
35114
35111
  valType: 'enumerated',
35115
35112
  values: [
35116
35113
  'outside', 'inside',
35117
35114
  'outside top', 'inside top',
35115
+ 'outside left', 'inside left',
35116
+ 'outside right', 'inside right',
35118
35117
  'outside bottom', 'inside bottom'
35119
35118
  ],
35120
35119
  dflt: 'outside',
35121
35120
  },
35121
+
35122
35122
  ticklen: axesAttrs.ticklen,
35123
35123
  tickwidth: axesAttrs.tickwidth,
35124
35124
  tickcolor: axesAttrs.tickcolor,
@@ -35145,7 +35145,6 @@ module.exports = overrideAll({
35145
35145
  side: {
35146
35146
  valType: 'enumerated',
35147
35147
  values: ['right', 'top', 'bottom'],
35148
- dflt: 'top',
35149
35148
  }
35150
35149
  },
35151
35150
 
@@ -35204,23 +35203,30 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
35204
35203
  return Lib.coerce(colorbarIn, colorbarOut, attributes, attr, dflt);
35205
35204
  }
35206
35205
 
35206
+ var margin = layout.margin || {t: 0, b: 0, l: 0, r: 0};
35207
+ var w = layout.width - margin.l - margin.r;
35208
+ var h = layout.height - margin.t - margin.b;
35209
+
35210
+ var orientation = coerce('orientation');
35211
+ var isVertical = orientation === 'v';
35212
+
35207
35213
  var thicknessmode = coerce('thicknessmode');
35208
35214
  coerce('thickness', (thicknessmode === 'fraction') ?
35209
- 30 / (layout.width - layout.margin.l - layout.margin.r) :
35215
+ 30 / (isVertical ? w : h) :
35210
35216
  30
35211
35217
  );
35212
35218
 
35213
35219
  var lenmode = coerce('lenmode');
35214
35220
  coerce('len', (lenmode === 'fraction') ?
35215
35221
  1 :
35216
- layout.height - layout.margin.t - layout.margin.b
35222
+ isVertical ? h : w
35217
35223
  );
35218
35224
 
35219
- coerce('x');
35220
- coerce('xanchor');
35225
+ coerce('x', isVertical ? 1.02 : 0.5);
35226
+ coerce('xanchor', isVertical ? 'left' : 'center');
35221
35227
  coerce('xpad');
35222
- coerce('y');
35223
- coerce('yanchor');
35228
+ coerce('y', isVertical ? 0.5 : 1.02);
35229
+ coerce('yanchor', isVertical ? 'middle' : 'bottom');
35224
35230
  coerce('ypad');
35225
35231
  Lib.noneOrAll(colorbarIn, colorbarOut, ['x', 'y']);
35226
35232
 
@@ -35230,7 +35236,22 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
35230
35236
  coerce('borderwidth');
35231
35237
  coerce('bgcolor');
35232
35238
 
35233
- var ticklabelposition = coerce('ticklabelposition');
35239
+ var ticklabelposition = Lib.coerce(colorbarIn, colorbarOut, {
35240
+ ticklabelposition: {
35241
+ valType: 'enumerated',
35242
+ dflt: 'outside',
35243
+ values: isVertical ? [
35244
+ 'outside', 'inside',
35245
+ 'outside top', 'inside top',
35246
+ 'outside bottom', 'inside bottom'
35247
+ ] : [
35248
+ 'outside', 'inside',
35249
+ 'outside left', 'inside left',
35250
+ 'outside right', 'inside right'
35251
+ ]
35252
+ }
35253
+ }, 'ticklabelposition');
35254
+
35234
35255
  coerce('ticklabeloverflow', ticklabelposition.indexOf('inside') !== -1 ? 'hide past domain' : 'hide past div');
35235
35256
 
35236
35257
  handleTickValueDefaults(colorbarIn, colorbarOut, coerce, 'linear');
@@ -35252,7 +35273,7 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
35252
35273
  size: Lib.bigFont(tickFont.size)
35253
35274
  });
35254
35275
  Lib.coerceFont(coerce, 'title.font', dfltTitleFont);
35255
- coerce('title.side');
35276
+ coerce('title.side', isVertical ? 'top' : 'right');
35256
35277
  };
35257
35278
 
35258
35279
  },{"../../lib":388,"../../plot_api/plot_template":427,"../../plots/cartesian/prefix_suffix_defaults":457,"../../plots/cartesian/tick_label_defaults":462,"../../plots/cartesian/tick_mark_defaults":463,"../../plots/cartesian/tick_value_defaults":464,"./attributes":257}],260:[function(_dereq_,module,exports){
@@ -35425,18 +35446,20 @@ function makeColorBarData(gd) {
35425
35446
  }
35426
35447
 
35427
35448
  function drawColorBar(g, opts, gd) {
35449
+ var isVertical = opts.orientation === 'v';
35428
35450
  var len = opts.len;
35429
35451
  var lenmode = opts.lenmode;
35430
35452
  var thickness = opts.thickness;
35431
35453
  var thicknessmode = opts.thicknessmode;
35432
35454
  var outlinewidth = opts.outlinewidth;
35433
35455
  var borderwidth = opts.borderwidth;
35456
+ var bgcolor = opts.bgcolor;
35434
35457
  var xanchor = opts.xanchor;
35435
35458
  var yanchor = opts.yanchor;
35436
35459
  var xpad = opts.xpad;
35437
35460
  var ypad = opts.ypad;
35438
35461
  var optsX = opts.x;
35439
- var optsY = opts.y;
35462
+ var optsY = isVertical ? opts.y : 1 - opts.y;
35440
35463
 
35441
35464
  var fullLayout = gd._fullLayout;
35442
35465
  var gs = fullLayout._size;
@@ -35467,23 +35490,35 @@ function drawColorBar(g, opts, gd) {
35467
35490
  // when the colorbar itself is pushing the margins.
35468
35491
  // but then the fractional size is calculated based on the
35469
35492
  // actual graph size, so that the axes will size correctly.
35470
- var thickPx = Math.round(thickness * (thicknessmode === 'fraction' ? gs.w : 1));
35471
- var thickFrac = thickPx / gs.w;
35472
- var lenPx = Math.round(len * (lenmode === 'fraction' ? gs.h : 1));
35473
- var lenFrac = lenPx / gs.h;
35474
- var xpadFrac = xpad / gs.w;
35475
- var yExtraPx = (borderwidth + outlinewidth) / 2;
35476
- var ypadFrac = ypad / gs.h;
35493
+ var thickPx = Math.round(thickness * (thicknessmode === 'fraction' ? (isVertical ? gs.w : gs.h) : 1));
35494
+ var thickFrac = thickPx / (isVertical ? gs.w : gs.h);
35495
+ var lenPx = Math.round(len * (lenmode === 'fraction' ? (isVertical ? gs.h : gs.w) : 1));
35496
+ var lenFrac = lenPx / (isVertical ? gs.h : gs.w);
35477
35497
 
35478
35498
  // x positioning: do it initially just for left anchor,
35479
35499
  // then fix at the end (since we don't know the width yet)
35480
- var uPx = Math.round(optsX * gs.w + xpad);
35481
- // for dragging... this is getting a little muddled...
35482
- var uFrac = optsX - thickFrac * ({center: 0.5, right: 1}[xanchor] || 0);
35500
+ var uPx = Math.round(isVertical ?
35501
+ optsX * gs.w + xpad :
35502
+ optsY * gs.h + ypad
35503
+ );
35483
35504
 
35484
- // y positioning we can do correctly from the start
35485
- var vFrac = optsY + lenFrac * (({top: -0.5, bottom: 0.5}[yanchor] || 0) - 0.5);
35486
- var vPx = Math.round(gs.h * (1 - vFrac));
35505
+ var xRatio = {center: 0.5, right: 1}[xanchor] || 0;
35506
+ var yRatio = {top: 1, middle: 0.5}[yanchor] || 0;
35507
+
35508
+ // for dragging... this is getting a little muddled...
35509
+ var uFrac = isVertical ?
35510
+ optsX - xRatio * thickFrac :
35511
+ optsY - yRatio * thickFrac;
35512
+
35513
+ // y/x positioning (for v/h) we can do correctly from the start
35514
+ var vFrac = isVertical ?
35515
+ optsY - yRatio * lenFrac :
35516
+ optsX - xRatio * lenFrac;
35517
+
35518
+ var vPx = Math.round(isVertical ?
35519
+ gs.h * (1 - vFrac) :
35520
+ gs.w * vFrac
35521
+ );
35487
35522
 
35488
35523
  // stash a few things for makeEditable
35489
35524
  opts._lenFrac = lenFrac;
@@ -35496,12 +35531,23 @@ function drawColorBar(g, opts, gd) {
35496
35531
 
35497
35532
  // position can't go in through supplyDefaults
35498
35533
  // because that restricts it to [0,1]
35499
- ax.position = optsX + xpadFrac + thickFrac;
35534
+ ax.position = thickFrac + (isVertical ?
35535
+ optsX + xpad / gs.w :
35536
+ optsY + ypad / gs.h
35537
+ );
35538
+
35539
+ var topOrBottom = ['top', 'bottom'].indexOf(titleSide) !== -1;
35540
+
35541
+ if(isVertical && topOrBottom) {
35542
+ ax.title.side = titleSide;
35543
+ ax.titlex = optsX + xpad / gs.w;
35544
+ ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypad / gs.h : ypad / gs.h);
35545
+ }
35500
35546
 
35501
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
35547
+ if(!isVertical && !topOrBottom) {
35502
35548
  ax.title.side = titleSide;
35503
- ax.titlex = optsX + xpadFrac;
35504
- ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
35549
+ ax.titley = optsY + ypad / gs.h;
35550
+ ax.titlex = vFrac + xpad / gs.w; // right side
35505
35551
  }
35506
35552
 
35507
35553
  if(line.color && opts.tickmode === 'auto') {
@@ -35526,9 +35572,12 @@ function drawColorBar(g, opts, gd) {
35526
35572
 
35527
35573
  // set domain after init, because we may want to
35528
35574
  // allow it outside [0,1]
35529
- ax.domain = [
35530
- vFrac + ypadFrac,
35531
- vFrac + lenFrac - ypadFrac
35575
+ ax.domain = isVertical ? [
35576
+ vFrac + ypad / gs.h,
35577
+ vFrac + lenFrac - ypad / gs.h
35578
+ ] : [
35579
+ vFrac + xpad / gs.w,
35580
+ vFrac + lenFrac - xpad / gs.w
35532
35581
  ];
35533
35582
 
35534
35583
  ax.setScale();
@@ -35538,9 +35587,13 @@ function drawColorBar(g, opts, gd) {
35538
35587
  var titleCont = g.select('.' + cn.cbtitleunshift)
35539
35588
  .attr('transform', strTranslate(-Math.round(gs.l), -Math.round(gs.t)));
35540
35589
 
35590
+ var ticklabelposition = ax.ticklabelposition;
35591
+ var titleFontSize = ax.title.font.size;
35592
+
35541
35593
  var axLayer = g.select('.' + cn.cbaxis);
35542
35594
  var titleEl;
35543
35595
  var titleHeight = 0;
35596
+ var titleWidth = 0;
35544
35597
 
35545
35598
  function drawTitle(titleClass, titleOpts) {
35546
35599
  var dfltTitleOpts = {
@@ -35565,54 +35618,98 @@ function drawColorBar(g, opts, gd) {
35565
35618
  }
35566
35619
 
35567
35620
  function drawDummyTitle() {
35568
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
35569
- // draw the title so we know how much room it needs
35570
- // when we squish the axis. This one only applies to
35571
- // top or bottom titles, not right side.
35572
- var x = gs.l + (optsX + xpadFrac) * gs.w;
35573
- var fontSize = ax.title.font.size;
35574
- var y;
35621
+ // draw the title so we know how much room it needs
35622
+ // when we squish the axis.
35623
+ // On vertical colorbars this only applies to top or bottom titles, not right side.
35624
+ // On horizontal colorbars this only applies to right, etc.
35625
+
35626
+ if(
35627
+ (isVertical && topOrBottom) ||
35628
+ (!isVertical && !topOrBottom)
35629
+ ) {
35630
+ var x, y;
35575
35631
 
35576
35632
  if(titleSide === 'top') {
35577
- y = (1 - (vFrac + lenFrac - ypadFrac)) * gs.h +
35578
- gs.t + 3 + fontSize * 0.75;
35579
- } else {
35580
- y = (1 - (vFrac + ypadFrac)) * gs.h +
35581
- gs.t - 3 - fontSize * 0.25;
35633
+ x = xpad + gs.l + gs.w * optsX;
35634
+ y = ypad + gs.t + gs.h * (1 - vFrac - lenFrac) + 3 + titleFontSize * 0.75;
35582
35635
  }
35636
+
35637
+ if(titleSide === 'bottom') {
35638
+ x = xpad + gs.l + gs.w * optsX;
35639
+ y = ypad + gs.t + gs.h * (1 - vFrac) - 3 - titleFontSize * 0.25;
35640
+ }
35641
+
35642
+ if(titleSide === 'right') {
35643
+ y = ypad + gs.t + gs.h * optsY + 3 + titleFontSize * 0.75;
35644
+ x = xpad + gs.l + gs.w * vFrac;
35645
+ }
35646
+
35583
35647
  drawTitle(ax._id + 'title', {
35584
- attributes: {x: x, y: y, 'text-anchor': 'start'}
35648
+ attributes: {x: x, y: y, 'text-anchor': isVertical ? 'start' : 'middle'}
35585
35649
  });
35586
35650
  }
35587
35651
  }
35588
35652
 
35589
35653
  function drawCbTitle() {
35590
- if(['top', 'bottom'].indexOf(titleSide) === -1) {
35591
- var fontSize = ax.title.font.size;
35592
- var y = ax._offset + ax._length / 2;
35593
- var x = gs.l + (ax.position || 0) * gs.w + ((ax.side === 'right') ?
35594
- 10 + fontSize * ((ax.showticklabels ? 1 : 0.5)) :
35595
- -10 - fontSize * ((ax.showticklabels ? 0.5 : 0)));
35596
-
35597
- // the 'h' + is a hack to get around the fact that
35598
- // convertToTspans rotates any 'y...' class by 90 degrees.
35599
- // TODO: find a better way to control this.
35600
- drawTitle('h' + ax._id + 'title', {
35654
+ if(
35655
+ (isVertical && !topOrBottom) ||
35656
+ (!isVertical && topOrBottom)
35657
+ ) {
35658
+ var pos = ax.position || 0;
35659
+ var mid = ax._offset + ax._length / 2;
35660
+ var x, y;
35661
+
35662
+ if(titleSide === 'right') {
35663
+ y = mid;
35664
+ x = gs.l + gs.w * pos + 10 + titleFontSize * (
35665
+ ax.showticklabels ? 1 : 0.5
35666
+ );
35667
+ } else {
35668
+ x = mid;
35669
+
35670
+ if(titleSide === 'bottom') {
35671
+ y = gs.t + gs.h * pos + 10 + (
35672
+ ticklabelposition.indexOf('inside') === -1 ?
35673
+ ax.tickfont.size :
35674
+ 0
35675
+ ) + (
35676
+ ax.ticks !== 'intside' ?
35677
+ opts.ticklen || 0 :
35678
+ 0
35679
+ );
35680
+ }
35681
+
35682
+ if(titleSide === 'top') {
35683
+ var nlines = title.text.split('<br>').length;
35684
+ y = gs.t + gs.h * pos + 10 - thickPx - LINE_SPACING * titleFontSize * nlines;
35685
+ }
35686
+ }
35687
+
35688
+ drawTitle((isVertical ?
35689
+ // the 'h' + is a hack to get around the fact that
35690
+ // convertToTspans rotates any 'y...' class by 90 degrees.
35691
+ // TODO: find a better way to control this.
35692
+ 'h' :
35693
+ 'v'
35694
+ ) + ax._id + 'title', {
35601
35695
  avoid: {
35602
35696
  selection: d3.select(gd).selectAll('g.' + ax._id + 'tick'),
35603
35697
  side: titleSide,
35604
- offsetLeft: gs.l,
35605
- offsetTop: 0,
35606
- maxShift: fullLayout.width
35698
+ offsetTop: isVertical ? 0 : gs.t,
35699
+ offsetLeft: isVertical ? gs.l : 0,
35700
+ maxShift: isVertical ? fullLayout.width : fullLayout.height
35607
35701
  },
35608
35702
  attributes: {x: x, y: y, 'text-anchor': 'middle'},
35609
- transform: {rotate: '-90', offset: 0}
35703
+ transform: {rotate: isVertical ? -90 : 0, offset: 0}
35610
35704
  });
35611
35705
  }
35612
35706
  }
35613
35707
 
35614
35708
  function drawAxis() {
35615
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
35709
+ if(
35710
+ (!isVertical && !topOrBottom) ||
35711
+ (isVertical && topOrBottom)
35712
+ ) {
35616
35713
  // squish the axis top to make room for the title
35617
35714
  var titleGroup = g.select('.' + cn.cbtitle);
35618
35715
  var titleText = titleGroup.select('text');
@@ -35624,39 +35721,63 @@ function drawColorBar(g, opts, gd) {
35624
35721
  if(titleText.node()) {
35625
35722
  lineSize = parseInt(titleText.node().style.fontSize, 10) * LINE_SPACING;
35626
35723
  }
35724
+
35725
+ var bb;
35627
35726
  if(mathJaxNode) {
35628
- titleHeight = Drawing.bBox(mathJaxNode).height;
35727
+ bb = Drawing.bBox(mathJaxNode);
35728
+ titleWidth = bb.width;
35729
+ titleHeight = bb.height;
35629
35730
  if(titleHeight > lineSize) {
35630
35731
  // not entirely sure how mathjax is doing
35631
35732
  // vertical alignment, but this seems to work.
35632
35733
  titleTrans[1] -= (titleHeight - lineSize) / 2;
35633
35734
  }
35634
35735
  } else if(titleText.node() && !titleText.classed(cn.jsPlaceholder)) {
35635
- titleHeight = Drawing.bBox(titleText.node()).height;
35736
+ bb = Drawing.bBox(titleText.node());
35737
+ titleWidth = bb.width;
35738
+ titleHeight = bb.height;
35636
35739
  }
35637
- if(titleHeight) {
35638
- // buffer btwn colorbar and title
35639
- // TODO: configurable
35640
- titleHeight += 5;
35641
35740
 
35642
- if(titleSide === 'top') {
35643
- ax.domain[1] -= titleHeight / gs.h;
35644
- titleTrans[1] *= -1;
35645
- } else {
35646
- ax.domain[0] += titleHeight / gs.h;
35647
- var nlines = svgTextUtils.lineCount(titleText);
35648
- titleTrans[1] += (1 - nlines) * lineSize;
35741
+ if(isVertical) {
35742
+ if(titleHeight) {
35743
+ // buffer btwn colorbar and title
35744
+ // TODO: configurable
35745
+ titleHeight += 5;
35746
+
35747
+ if(titleSide === 'top') {
35748
+ ax.domain[1] -= titleHeight / gs.h;
35749
+ titleTrans[1] *= -1;
35750
+ } else {
35751
+ ax.domain[0] += titleHeight / gs.h;
35752
+ var nlines = svgTextUtils.lineCount(titleText);
35753
+ titleTrans[1] += (1 - nlines) * lineSize;
35754
+ }
35755
+
35756
+ titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
35757
+ ax.setScale();
35649
35758
  }
35759
+ } else { // horizontal colorbars
35760
+ if(titleWidth) {
35761
+ if(titleSide === 'right') {
35762
+ ax.domain[0] += (titleWidth + titleFontSize / 2) / gs.w;
35763
+ }
35650
35764
 
35651
- titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
35652
- ax.setScale();
35765
+ titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
35766
+ ax.setScale();
35767
+ }
35653
35768
  }
35654
35769
  }
35655
35770
 
35656
35771
  g.selectAll('.' + cn.cbfills + ',.' + cn.cblines)
35657
- .attr('transform', strTranslate(0, Math.round(gs.h * (1 - ax.domain[1]))));
35772
+ .attr('transform', isVertical ?
35773
+ strTranslate(0, Math.round(gs.h * (1 - ax.domain[1]))) :
35774
+ strTranslate(Math.round(gs.w * ax.domain[0]), 0)
35775
+ );
35658
35776
 
35659
- axLayer.attr('transform', strTranslate(0, Math.round(-gs.t)));
35777
+ axLayer.attr('transform', isVertical ?
35778
+ strTranslate(0, Math.round(-gs.t)) :
35779
+ strTranslate(Math.round(-gs.l), 0)
35780
+ );
35660
35781
 
35661
35782
  var fills = g.select('.' + cn.cbfills)
35662
35783
  .selectAll('rect.' + cn.cbfill)
@@ -35682,20 +35803,22 @@ function drawColorBar(g, opts, gd) {
35682
35803
 
35683
35804
  // offset the side adjoining the next rectangle so they
35684
35805
  // overlap, to prevent antialiasing gaps
35685
- z[1] = Lib.constrain(z[1] + (z[1] > z[0]) ? 1 : -1, zBounds[0], zBounds[1]);
35686
-
35806
+ if(isVertical) {
35807
+ z[1] = Lib.constrain(z[1] + (z[1] > z[0]) ? 1 : -1, zBounds[0], zBounds[1]);
35808
+ } /* else {
35809
+ // TODO: horizontal case
35810
+ } */
35687
35811
 
35688
35812
  // Colorbar cannot currently support opacities so we
35689
35813
  // use an opaque fill even when alpha channels present
35690
- var fillEl = d3.select(this).attr({
35691
- x: uPx,
35692
- width: Math.max(thickPx, 2),
35693
- y: d3.min(z),
35694
- height: Math.max(d3.max(z) - d3.min(z), 2),
35695
- });
35814
+ var fillEl = d3.select(this)
35815
+ .attr(isVertical ? 'x' : 'y', uPx)
35816
+ .attr(isVertical ? 'y' : 'x', d3.min(z))
35817
+ .attr(isVertical ? 'width' : 'height', Math.max(thickPx, 2))
35818
+ .attr(isVertical ? 'height' : 'width', Math.max(d3.max(z) - d3.min(z), 2));
35696
35819
 
35697
35820
  if(opts._fillgradient) {
35698
- Drawing.gradient(fillEl, gd, opts._id, 'vertical', opts._fillgradient, 'fill');
35821
+ Drawing.gradient(fillEl, gd, opts._id, isVertical ? 'vertical' : 'horizontalreversed', opts._fillgradient, 'fill');
35699
35822
  } else {
35700
35823
  // tinycolor can't handle exponents and
35701
35824
  // at this scale, removing it makes no difference.
@@ -35711,9 +35834,15 @@ function drawColorBar(g, opts, gd) {
35711
35834
  .classed(cn.cbline, true);
35712
35835
  lines.exit().remove();
35713
35836
  lines.each(function(d) {
35837
+ var a = uPx;
35838
+ var b = (Math.round(ax.c2p(d)) + (line.width / 2) % 1);
35839
+
35714
35840
  d3.select(this)
35715
- .attr('d', 'M' + uPx + ',' +
35716
- (Math.round(ax.c2p(d)) + (line.width / 2) % 1) + 'h' + thickPx)
35841
+ .attr('d', 'M' +
35842
+ (isVertical ? a + ',' + b : b + ',' + a) +
35843
+ (isVertical ? 'h' : 'v') +
35844
+ thickPx
35845
+ )
35717
35846
  .call(Drawing.lineGroupStyle, line.width, lineColormap(d), line.dash);
35718
35847
  });
35719
35848
 
@@ -35746,82 +35875,211 @@ function drawColorBar(g, opts, gd) {
35746
35875
  // TODO: why are we redrawing multiple times now with this?
35747
35876
  // I guess autoMargin doesn't like being post-promise?
35748
35877
  function positionCB() {
35878
+ var bb;
35749
35879
  var innerThickness = thickPx + outlinewidth / 2;
35750
- if(ax.ticklabelposition.indexOf('inside') === -1) {
35751
- innerThickness += Drawing.bBox(axLayer.node()).width;
35880
+ if(ticklabelposition.indexOf('inside') === -1) {
35881
+ bb = Drawing.bBox(axLayer.node());
35882
+ innerThickness += isVertical ? bb.width : bb.height;
35752
35883
  }
35753
35884
 
35754
35885
  titleEl = titleCont.select('text');
35755
35886
 
35887
+ var titleWidth = 0;
35888
+
35889
+ var topSideVertical = isVertical && titleSide === 'top';
35890
+ var rightSideHorizontal = !isVertical && titleSide === 'right';
35891
+
35892
+ var moveY = 0;
35893
+
35756
35894
  if(titleEl.node() && !titleEl.classed(cn.jsPlaceholder)) {
35895
+ var _titleHeight;
35896
+
35757
35897
  var mathJaxNode = titleCont.select('.h' + ax._id + 'title-math-group').node();
35758
- var titleWidth;
35759
- if(mathJaxNode && ['top', 'bottom'].indexOf(titleSide) !== -1) {
35760
- titleWidth = Drawing.bBox(mathJaxNode).width;
35898
+ if(mathJaxNode && (
35899
+ (isVertical && topOrBottom) ||
35900
+ (!isVertical && !topOrBottom)
35901
+ )) {
35902
+ bb = Drawing.bBox(mathJaxNode);
35903
+ titleWidth = bb.width;
35904
+ _titleHeight = bb.height;
35761
35905
  } else {
35762
35906
  // note: the formula below works for all title sides,
35763
35907
  // (except for top/bottom mathjax, above)
35764
35908
  // but the weird gs.l is because the titleunshift
35765
35909
  // transform gets removed by Drawing.bBox
35766
- titleWidth = Drawing.bBox(titleCont.node()).right - uPx - gs.l;
35910
+ bb = Drawing.bBox(titleCont.node());
35911
+ titleWidth = bb.right - gs.l - (isVertical ? uPx : vPx);
35912
+ _titleHeight = bb.bottom - gs.t - (isVertical ? vPx : uPx);
35913
+
35914
+ if(
35915
+ !isVertical && titleSide === 'top'
35916
+ ) {
35917
+ innerThickness += bb.height;
35918
+ moveY = bb.height;
35919
+ }
35920
+ }
35921
+
35922
+ if(rightSideHorizontal) {
35923
+ titleEl.attr('transform', strTranslate(titleWidth / 2 + titleFontSize / 2, 0));
35924
+
35925
+ titleWidth *= 2;
35767
35926
  }
35768
- innerThickness = Math.max(innerThickness, titleWidth);
35927
+
35928
+ innerThickness = Math.max(innerThickness,
35929
+ isVertical ? titleWidth : _titleHeight
35930
+ );
35769
35931
  }
35770
35932
 
35771
- var outerThickness = 2 * xpad + innerThickness + borderwidth + outlinewidth / 2;
35933
+ var outerThickness = (isVertical ?
35934
+ xpad :
35935
+ ypad
35936
+ ) * 2 + innerThickness + borderwidth + outlinewidth / 2;
35772
35937
 
35773
- g.select('.' + cn.cbbg).attr({
35774
- x: uPx - xpad - (borderwidth + outlinewidth) / 2,
35775
- y: vPx - lenPx - yExtraPx,
35776
- width: Math.max(outerThickness, 2),
35777
- height: Math.max(lenPx + 2 * yExtraPx, 2)
35778
- })
35779
- .call(Color.fill, opts.bgcolor)
35938
+ var hColorbarMoveTitle = 0;
35939
+ if(!isVertical && title.text && yanchor === 'bottom' && optsY <= 0) {
35940
+ hColorbarMoveTitle = outerThickness / 2;
35941
+
35942
+ outerThickness += hColorbarMoveTitle;
35943
+ moveY += hColorbarMoveTitle;
35944
+ }
35945
+ fullLayout._hColorbarMoveTitle = hColorbarMoveTitle;
35946
+ fullLayout._hColorbarMoveCBTitle = moveY;
35947
+
35948
+ var extraW = borderwidth + outlinewidth;
35949
+
35950
+ g.select('.' + cn.cbbg)
35951
+ .attr('x', (isVertical ? uPx : vPx) - extraW / 2 - (isVertical ? xpad : 0))
35952
+ .attr('y', (isVertical ? vPx : uPx) - (isVertical ? lenPx : ypad + moveY - hColorbarMoveTitle))
35953
+ .attr(isVertical ? 'width' : 'height', Math.max(outerThickness - hColorbarMoveTitle, 2))
35954
+ .attr(isVertical ? 'height' : 'width', Math.max(lenPx + extraW, 2))
35955
+ .call(Color.fill, bgcolor)
35780
35956
  .call(Color.stroke, opts.bordercolor)
35781
35957
  .style('stroke-width', borderwidth);
35782
35958
 
35783
- g.selectAll('.' + cn.cboutline).attr({
35784
- x: uPx,
35785
- y: vPx - lenPx + ypad + (titleSide === 'top' ? titleHeight : 0),
35786
- width: Math.max(thickPx, 2),
35787
- height: Math.max(lenPx - 2 * ypad - titleHeight, 2)
35788
- })
35959
+ var moveX = rightSideHorizontal ? Math.max(titleWidth - 10, 0) : 0;
35960
+
35961
+ g.selectAll('.' + cn.cboutline)
35962
+ .attr('x', (isVertical ? uPx : vPx + xpad) + moveX)
35963
+ .attr('y', (isVertical ? vPx + ypad - lenPx : uPx) + (topSideVertical ? titleHeight : 0))
35964
+ .attr(isVertical ? 'width' : 'height', Math.max(thickPx, 2))
35965
+ .attr(isVertical ? 'height' : 'width', Math.max(lenPx - (isVertical ?
35966
+ 2 * ypad + titleHeight :
35967
+ 2 * xpad + moveX
35968
+ ), 2))
35789
35969
  .call(Color.stroke, opts.outlinecolor)
35790
35970
  .style({
35791
35971
  fill: 'none',
35792
35972
  'stroke-width': outlinewidth
35793
35973
  });
35794
35974
 
35795
- // fix positioning for xanchor!='left'
35796
- var xoffset = ({center: 0.5, right: 1}[xanchor] || 0) * outerThickness;
35797
- g.attr('transform', strTranslate(gs.l - xoffset, gs.t));
35975
+ g.attr('transform', strTranslate(
35976
+ gs.l - (isVertical ? xRatio * outerThickness : 0),
35977
+ gs.t - (isVertical ? 0 : (1 - yRatio) * outerThickness - moveY)
35978
+ ));
35979
+
35980
+ if(!isVertical && (
35981
+ borderwidth || (
35982
+ tinycolor(bgcolor).getAlpha() &&
35983
+ !tinycolor.equals(fullLayout.paper_bgcolor, bgcolor)
35984
+ )
35985
+ )) {
35986
+ // for horizontal colorbars when there is a border line or having different background color
35987
+ // hide/adjust x positioning for the first/last tick labels if they go outside the border
35988
+ var tickLabels = axLayer.selectAll('text');
35989
+ var numTicks = tickLabels[0].length;
35990
+
35991
+ var border = g.select('.' + cn.cbbg).node();
35992
+ var oBb = Drawing.bBox(border);
35993
+ var oTr = Drawing.getTranslate(g);
35994
+
35995
+ var TEXTPAD = 2;
35996
+
35997
+ tickLabels.each(function(d, i) {
35998
+ var first = 0;
35999
+ var last = numTicks - 1;
36000
+ if(i === first || i === last) {
36001
+ var iBb = Drawing.bBox(this);
36002
+ var iTr = Drawing.getTranslate(this);
36003
+ var deltaX;
36004
+
36005
+ if(i === last) {
36006
+ var iRight = iBb.right + iTr.x;
36007
+ var oRight = oBb.right + oTr.x + vPx - borderwidth - TEXTPAD + optsX;
36008
+
36009
+ deltaX = oRight - iRight;
36010
+ if(deltaX > 0) deltaX = 0;
36011
+ } else if(i === first) {
36012
+ var iLeft = iBb.left + iTr.x;
36013
+ var oLeft = oBb.left + oTr.x + vPx + borderwidth + TEXTPAD;
36014
+
36015
+ deltaX = oLeft - iLeft;
36016
+ if(deltaX < 0) deltaX = 0;
36017
+ }
36018
+
36019
+ if(deltaX) {
36020
+ if(numTicks < 3) { // adjust position
36021
+ this.setAttribute('transform',
36022
+ 'translate(' + deltaX + ',0) ' +
36023
+ this.getAttribute('transform')
36024
+ );
36025
+ } else { // hide
36026
+ this.setAttribute('visibility', 'hidden');
36027
+ }
36028
+ }
36029
+ }
36030
+ });
36031
+ }
35798
36032
 
35799
36033
  // auto margin adjustment
35800
36034
  var marginOpts = {};
36035
+ var lFrac = FROM_TL[xanchor];
36036
+ var rFrac = FROM_BR[xanchor];
35801
36037
  var tFrac = FROM_TL[yanchor];
35802
36038
  var bFrac = FROM_BR[yanchor];
35803
- if(lenmode === 'pixels') {
35804
- marginOpts.y = optsY;
35805
- marginOpts.t = lenPx * tFrac;
35806
- marginOpts.b = lenPx * bFrac;
35807
- } else {
35808
- marginOpts.t = marginOpts.b = 0;
35809
- marginOpts.yt = optsY + len * tFrac;
35810
- marginOpts.yb = optsY - len * bFrac;
35811
- }
35812
36039
 
35813
- var lFrac = FROM_TL[xanchor];
35814
- var rFrac = FROM_BR[xanchor];
35815
- if(thicknessmode === 'pixels') {
35816
- marginOpts.x = optsX;
35817
- marginOpts.l = outerThickness * lFrac;
35818
- marginOpts.r = outerThickness * rFrac;
35819
- } else {
35820
- var extraThickness = outerThickness - thickPx;
35821
- marginOpts.l = extraThickness * lFrac;
35822
- marginOpts.r = extraThickness * rFrac;
35823
- marginOpts.xl = optsX - thickness * lFrac;
35824
- marginOpts.xr = optsX + thickness * rFrac;
36040
+ var extraThickness = outerThickness - thickPx;
36041
+ if(isVertical) {
36042
+ if(lenmode === 'pixels') {
36043
+ marginOpts.y = optsY;
36044
+ marginOpts.t = lenPx * tFrac;
36045
+ marginOpts.b = lenPx * bFrac;
36046
+ } else {
36047
+ marginOpts.t = marginOpts.b = 0;
36048
+ marginOpts.yt = optsY + len * tFrac;
36049
+ marginOpts.yb = optsY - len * bFrac;
36050
+ }
36051
+
36052
+ if(thicknessmode === 'pixels') {
36053
+ marginOpts.x = optsX;
36054
+ marginOpts.l = outerThickness * lFrac;
36055
+ marginOpts.r = outerThickness * rFrac;
36056
+ } else {
36057
+ marginOpts.l = extraThickness * lFrac;
36058
+ marginOpts.r = extraThickness * rFrac;
36059
+ marginOpts.xl = optsX - thickness * lFrac;
36060
+ marginOpts.xr = optsX + thickness * rFrac;
36061
+ }
36062
+ } else { // horizontal colorbars
36063
+ if(lenmode === 'pixels') {
36064
+ marginOpts.x = optsX;
36065
+ marginOpts.l = lenPx * lFrac;
36066
+ marginOpts.r = lenPx * rFrac;
36067
+ } else {
36068
+ marginOpts.l = marginOpts.r = 0;
36069
+ marginOpts.xl = optsX + len * lFrac;
36070
+ marginOpts.xr = optsX - len * rFrac;
36071
+ }
36072
+
36073
+ if(thicknessmode === 'pixels') {
36074
+ marginOpts.y = 1 - optsY;
36075
+ marginOpts.t = outerThickness * tFrac;
36076
+ marginOpts.b = outerThickness * bFrac;
36077
+ } else {
36078
+ marginOpts.t = extraThickness * tFrac;
36079
+ marginOpts.b = extraThickness * bFrac;
36080
+ marginOpts.yt = optsY - thickness * tFrac;
36081
+ marginOpts.yb = optsY + thickness * bFrac;
36082
+ }
35825
36083
  }
35826
36084
 
35827
36085
  Plots.autoMargin(gd, opts._id, marginOpts);
@@ -35838,6 +36096,7 @@ function drawColorBar(g, opts, gd) {
35838
36096
  }
35839
36097
 
35840
36098
  function makeEditable(g, opts, gd) {
36099
+ var isVertical = opts.orientation === 'v';
35841
36100
  var fullLayout = gd._fullLayout;
35842
36101
  var gs = fullLayout._size;
35843
36102
  var t0, xf, yf;
@@ -35852,9 +36111,13 @@ function makeEditable(g, opts, gd) {
35852
36111
  moveFn: function(dx, dy) {
35853
36112
  g.attr('transform', t0 + strTranslate(dx, dy));
35854
36113
 
35855
- xf = dragElement.align(opts._uFrac + (dx / gs.w), opts._thickFrac,
36114
+ xf = dragElement.align(
36115
+ (isVertical ? opts._uFrac : opts._vFrac) + (dx / gs.w),
36116
+ isVertical ? opts._thickFrac : opts._lenFrac,
35856
36117
  0, 1, opts.xanchor);
35857
- yf = dragElement.align(opts._vFrac - (dy / gs.h), opts._lenFrac,
36118
+ yf = dragElement.align(
36119
+ (isVertical ? opts._vFrac : (1 - opts._uFrac)) - (dy / gs.h),
36120
+ isVertical ? opts._lenFrac : opts._thickFrac,
35858
36121
  0, 1, opts.yanchor);
35859
36122
 
35860
36123
  var csr = dragElement.getCursor(xf, yf, opts.xanchor, opts.yanchor);
@@ -35931,6 +36194,8 @@ function calcLevels(gd, opts, zrange) {
35931
36194
  function mockColorBarAxis(gd, opts, zrange) {
35932
36195
  var fullLayout = gd._fullLayout;
35933
36196
 
36197
+ var isVertical = opts.orientation === 'v';
36198
+
35934
36199
  var cbAxisIn = {
35935
36200
  type: 'linear',
35936
36201
  range: zrange,
@@ -35961,17 +36226,19 @@ function mockColorBarAxis(gd, opts, zrange) {
35961
36226
  title: opts.title,
35962
36227
  showline: true,
35963
36228
  anchor: 'free',
35964
- side: 'right',
36229
+ side: isVertical ? 'right' : 'bottom',
35965
36230
  position: 1
35966
36231
  };
35967
36232
 
36233
+ var letter = isVertical ? 'y' : 'x';
36234
+
35968
36235
  var cbAxisOut = {
35969
36236
  type: 'linear',
35970
- _id: 'y' + opts._id
36237
+ _id: letter + opts._id
35971
36238
  };
35972
36239
 
35973
36240
  var axisOptions = {
35974
- letter: 'y',
36241
+ letter: letter,
35975
36242
  font: fullLayout.font,
35976
36243
  noHover: true,
35977
36244
  noTickson: true,
@@ -41584,7 +41851,9 @@ function createHoverText(hoverData, opts) {
41584
41851
  orientation: 'v'
41585
41852
  }
41586
41853
  };
41587
- var mockLayoutOut = {};
41854
+ var mockLayoutOut = {
41855
+ font: font
41856
+ };
41588
41857
  legendSupplyDefaults(mockLayoutIn, mockLayoutOut, gd._fullData);
41589
41858
  var mockLegend = mockLayoutOut.legend;
41590
41859
 
@@ -41625,7 +41894,8 @@ function createHoverText(hoverData, opts) {
41625
41894
 
41626
41895
  // Draw unified hover label
41627
41896
  mockLegend._inHover = true;
41628
- mockLegend._groupTitleFont = font;
41897
+ mockLegend._groupTitleFont = hoverlabel.grouptitlefont;
41898
+
41629
41899
  legendDraw(gd, mockLegend);
41630
41900
 
41631
41901
  // Position the hover
@@ -42627,9 +42897,11 @@ var isUnifiedHover = _dereq_('./helpers').isUnifiedHover;
42627
42897
  module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts) {
42628
42898
  opts = opts || {};
42629
42899
 
42900
+ var hasLegend = contOut.legend;
42901
+
42630
42902
  function inheritFontAttr(attr) {
42631
42903
  if(!opts.font[attr]) {
42632
- opts.font[attr] = contOut.legend ? contOut.legend.font[attr] : contOut.font[attr];
42904
+ opts.font[attr] = hasLegend ? contOut.legend.font[attr] : contOut.font[attr];
42633
42905
  }
42634
42906
  }
42635
42907
 
@@ -42640,7 +42912,7 @@ module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts
42640
42912
  inheritFontAttr('family');
42641
42913
  inheritFontAttr('color');
42642
42914
 
42643
- if(contOut.legend) {
42915
+ if(hasLegend) {
42644
42916
  if(!opts.bgcolor) opts.bgcolor = Color.combine(contOut.legend.bgcolor, contOut.paper_bgcolor);
42645
42917
  if(!opts.bordercolor) opts.bordercolor = contOut.legend.bordercolor;
42646
42918
  } else {
@@ -42749,11 +43021,13 @@ function castHoverinfo(trace, fullLayout, ptNumber) {
42749
43021
 
42750
43022
  var constants = _dereq_('./constants');
42751
43023
 
42752
- var fontAttrs = _dereq_('../../plots/font_attributes')({
43024
+ var fontAttrs = _dereq_('../../plots/font_attributes');
43025
+
43026
+ var font = fontAttrs({
42753
43027
  editType: 'none',
42754
43028
  });
42755
- fontAttrs.family.dflt = constants.HOVERFONT;
42756
- fontAttrs.size.dflt = constants.HOVERFONTSIZE;
43029
+ font.family.dflt = constants.HOVERFONT;
43030
+ font.size.dflt = constants.HOVERFONTSIZE;
42757
43031
 
42758
43032
  module.exports = {
42759
43033
  clickmode: {
@@ -42809,7 +43083,10 @@ module.exports = {
42809
43083
  valType: 'color',
42810
43084
  editType: 'none',
42811
43085
  },
42812
- font: fontAttrs,
43086
+ font: font,
43087
+ grouptitlefont: fontAttrs({
43088
+ editType: 'none',
43089
+ }),
42813
43090
  align: {
42814
43091
  valType: 'enumerated',
42815
43092
  values: ['left', 'right', 'auto'],
@@ -42822,6 +43099,7 @@ module.exports = {
42822
43099
  dflt: 15,
42823
43100
  editType: 'none',
42824
43101
  },
43102
+
42825
43103
  editType: 'none'
42826
43104
  },
42827
43105
  selectdirection: {
@@ -42869,6 +43147,8 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut) {
42869
43147
  }
42870
43148
 
42871
43149
  handleHoverLabelDefaults(layoutIn, layoutOut, coerce);
43150
+
43151
+ Lib.coerceFont(coerce, 'hoverlabel.grouptitlefont', layoutOut.hoverlabel.font);
42872
43152
  };
42873
43153
 
42874
43154
  },{"../../lib":388,"./hoverlabel_defaults":294,"./hovermode_defaults":295,"./layout_attributes":297}],299:[function(_dereq_,module,exports){
@@ -43752,6 +44032,9 @@ module.exports = {
43752
44032
  font: fontAttrs({
43753
44033
  editType: 'legend',
43754
44034
  }),
44035
+ grouptitlefont: fontAttrs({
44036
+ editType: 'legend',
44037
+ }),
43755
44038
  orientation: {
43756
44039
  valType: 'enumerated',
43757
44040
  values: ['v', 'h'],
@@ -43875,6 +44158,7 @@ var Registry = _dereq_('../../registry');
43875
44158
  var Lib = _dereq_('../../lib');
43876
44159
  var Template = _dereq_('../../plot_api/plot_template');
43877
44160
 
44161
+ var plotsAttrs = _dereq_('../../plots/attributes');
43878
44162
  var attributes = _dereq_('./attributes');
43879
44163
  var basePlotLayoutAttributes = _dereq_('../../plots/layout_attributes');
43880
44164
  var helpers = _dereq_('./helpers');
@@ -43882,13 +44166,30 @@ var helpers = _dereq_('./helpers');
43882
44166
 
43883
44167
  module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
43884
44168
  var containerIn = layoutIn.legend || {};
44169
+ var containerOut = Template.newContainer(layoutOut, 'legend');
44170
+
44171
+ function coerce(attr, dflt) {
44172
+ return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
44173
+ }
44174
+
44175
+ var trace;
44176
+ var traceCoerce = function(attr, dflt) {
44177
+ var traceIn = trace._input;
44178
+ var traceOut = trace;
44179
+ return Lib.coerce(traceIn, traceOut, plotsAttrs, attr, dflt);
44180
+ };
44181
+
44182
+ var globalFont = layoutOut.font || {};
44183
+ var grouptitlefont = Lib.coerceFont(coerce, 'grouptitlefont', Lib.extendFlat({}, globalFont, {
44184
+ size: Math.round(globalFont.size * 1.1)
44185
+ }));
43885
44186
 
43886
44187
  var legendTraceCount = 0;
43887
44188
  var legendReallyHasATrace = false;
43888
44189
  var defaultOrder = 'normal';
43889
44190
 
43890
44191
  for(var i = 0; i < fullData.length; i++) {
43891
- var trace = fullData[i];
44192
+ trace = fullData[i];
43892
44193
 
43893
44194
  if(!trace.visible) continue;
43894
44195
 
@@ -43915,6 +44216,8 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
43915
44216
  legendTraceCount++;
43916
44217
  }
43917
44218
  }
44219
+
44220
+ Lib.coerceFont(traceCoerce, 'legendgrouptitle.font', grouptitlefont);
43918
44221
  }
43919
44222
 
43920
44223
  if((Registry.traceIs(trace, 'bar') && layoutOut.barmode === 'stack') ||
@@ -43933,13 +44236,10 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
43933
44236
  basePlotLayoutAttributes, 'showlegend',
43934
44237
  legendReallyHasATrace && legendTraceCount > 1);
43935
44238
 
43936
- if(showLegend === false && !containerIn.uirevision) return;
43937
-
43938
- var containerOut = Template.newContainer(layoutOut, 'legend');
44239
+ // delete legend
44240
+ if(showLegend === false) layoutOut.legend = undefined;
43939
44241
 
43940
- function coerce(attr, dflt) {
43941
- return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
43942
- }
44242
+ if(showLegend === false && !containerIn.uirevision) return;
43943
44243
 
43944
44244
  coerce('uirevision', layoutOut.uirevision);
43945
44245
 
@@ -44001,7 +44301,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
44001
44301
  }
44002
44302
  };
44003
44303
 
44004
- },{"../../lib":388,"../../plot_api/plot_template":427,"../../plots/layout_attributes":477,"../../registry":481,"./attributes":306,"./helpers":312}],309:[function(_dereq_,module,exports){
44304
+ },{"../../lib":388,"../../plot_api/plot_template":427,"../../plots/attributes":434,"../../plots/layout_attributes":477,"../../registry":481,"./attributes":306,"./helpers":312}],309:[function(_dereq_,module,exports){
44005
44305
  'use strict';
44006
44306
 
44007
44307
  var d3 = _dereq_('@plotly/d3');
@@ -52453,8 +52753,10 @@ function draw(gd, titleClass, options) {
52453
52753
 
52454
52754
  var elShouldExist = txt || editable;
52455
52755
 
52756
+ var hColorbarMoveTitle;
52456
52757
  if(!group) {
52457
52758
  group = Lib.ensureSingle(fullLayout._infolayer, 'g', 'g-' + titleClass);
52759
+ hColorbarMoveTitle = fullLayout._hColorbarMoveTitle;
52458
52760
  }
52459
52761
 
52460
52762
  var el = group.selectAll('text')
@@ -52478,13 +52780,17 @@ function draw(gd, titleClass, options) {
52478
52780
  function drawTitle(titleEl) {
52479
52781
  var transformVal;
52480
52782
 
52783
+ if(!transform && hColorbarMoveTitle) {
52784
+ transform = {};
52785
+ }
52786
+
52481
52787
  if(transform) {
52482
52788
  transformVal = '';
52483
52789
  if(transform.rotate) {
52484
52790
  transformVal += 'rotate(' + [transform.rotate, attributes.x, attributes.y] + ')';
52485
52791
  }
52486
- if(transform.offset) {
52487
- transformVal += strTranslate(0, transform.offset);
52792
+ if(transform.offset || hColorbarMoveTitle) {
52793
+ transformVal += strTranslate(0, (transform.offset || 0) - (hColorbarMoveTitle || 0));
52488
52794
  }
52489
52795
  } else {
52490
52796
  transformVal = null;
@@ -64196,7 +64502,7 @@ function cleanDeprecatedAttributeKeys(aobj) {
64196
64502
  if((key === 'title' || oldAxisTitleRegex.test(key) || colorbarRegex.test(key)) &&
64197
64503
  (typeof value === 'string' || typeof value === 'number')) {
64198
64504
  replace(key, key.replace('title', 'title.text'));
64199
- } else if(key.indexOf('titlefont') > -1) {
64505
+ } else if(key.indexOf('titlefont') > -1 && key.indexOf('grouptitlefont') === -1) {
64200
64506
  replace(key, key.replace('titlefont', 'title.font'));
64201
64507
  } else if(key.indexOf('titleposition') > -1) {
64202
64508
  replace(key, key.replace('titleposition', 'title.position'));
@@ -82064,6 +82370,9 @@ module.exports = function(opts) {
82064
82370
  // TODO - that's uber hacky... better solution?
82065
82371
  };
82066
82372
 
82373
+ if(opts.autoSize) attrs.size.dflt = 'auto';
82374
+ if(opts.autoColor) attrs.color.dflt = 'auto';
82375
+
82067
82376
  if(opts.arrayOk) {
82068
82377
  attrs.family.arrayOk = true;
82069
82378
  attrs.size.arrayOk = true;
@@ -83797,6 +84106,7 @@ module.exports = {
83797
84106
  valType: 'boolean',
83798
84107
  editType: 'legend',
83799
84108
  },
84109
+
83800
84110
  colorway: {
83801
84111
  valType: 'colorlist',
83802
84112
  dflt: colorAttrs.defaults,
@@ -85209,13 +85519,7 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac
85209
85519
  );
85210
85520
 
85211
85521
  coerce('legendgroup');
85212
- var titleText = coerce('legendgrouptitle.text');
85213
- if(titleText) {
85214
- Lib.coerceFont(coerce, 'legendgrouptitle.font', Lib.extendFlat({}, layout.font, {
85215
- size: Math.round(layout.font.size * 1.1) // default to larger font size
85216
- }));
85217
- }
85218
-
85522
+ coerce('legendgrouptitle.text');
85219
85523
  coerce('legendrank');
85220
85524
 
85221
85525
  traceOut._dfltShowLegend = true;
@@ -85363,16 +85667,14 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut, formatObj) {
85363
85667
 
85364
85668
  coerce('autotypenumbers');
85365
85669
 
85366
- var globalFont = Lib.coerceFont(coerce, 'font');
85367
-
85368
- coerce('title.text', layoutOut._dfltTitle.plot);
85670
+ var font = Lib.coerceFont(coerce, 'font');
85671
+ var fontSize = font.size;
85369
85672
 
85370
- Lib.coerceFont(coerce, 'title.font', {
85371
- family: globalFont.family,
85372
- size: Math.round(globalFont.size * 1.4),
85373
- color: globalFont.color
85374
- });
85673
+ Lib.coerceFont(coerce, 'title.font', Lib.extendFlat({}, font, {
85674
+ size: Math.round(fontSize * 1.4)
85675
+ }));
85375
85676
 
85677
+ coerce('title.text', layoutOut._dfltTitle.plot);
85376
85678
  coerce('title.xref');
85377
85679
  coerce('title.yref');
85378
85680
  coerce('title.x');
@@ -88631,8 +88933,10 @@ module.exports = function arraysToCalcdata(cd, trace) {
88631
88933
 
88632
88934
  var scatterAttrs = _dereq_('../scatter/attributes');
88633
88935
  var baseAttrs = _dereq_('../../plots/attributes');
88936
+ var fontAttrs = _dereq_('../../plots/font_attributes');
88634
88937
  var axisHoverFormat = _dereq_('../../plots/cartesian/axis_format_attributes').axisHoverFormat;
88635
88938
  var hovertemplateAttrs = _dereq_('../../plots/template_attributes').hovertemplateAttrs;
88939
+ var texttemplateAttrs = _dereq_('../../plots/template_attributes').texttemplateAttrs;
88636
88940
  var colorScaleAttrs = _dereq_('../../components/colorscale/attributes');
88637
88941
 
88638
88942
  var extendFlat = _dereq_('../../lib/extend').extendFlat;
@@ -88711,6 +89015,19 @@ module.exports = extendFlat({
88711
89015
  zhoverformat: axisHoverFormat('z', 1),
88712
89016
 
88713
89017
  hovertemplate: hovertemplateAttrs(),
89018
+ texttemplate: texttemplateAttrs({
89019
+ arrayOk: false,
89020
+ editType: 'plot'
89021
+ }, {
89022
+ keys: ['x', 'y', 'z', 'text']
89023
+ }),
89024
+ textfont: fontAttrs({
89025
+ editType: 'plot',
89026
+ autoSize: true,
89027
+ autoColor: true,
89028
+ colorEditType: 'style',
89029
+ }),
89030
+
88714
89031
  showlegend: extendFlat({}, baseAttrs.showlegend, {dflt: false})
88715
89032
  }, {
88716
89033
  transforms: undefined
@@ -88718,7 +89035,7 @@ module.exports = extendFlat({
88718
89035
  colorScaleAttrs('', {cLetter: 'z', autoColorDflt: false})
88719
89036
  );
88720
89037
 
88721
- },{"../../components/colorscale/attributes":263,"../../lib/extend":380,"../../plots/attributes":434,"../../plots/cartesian/axis_format_attributes":441,"../../plots/template_attributes":480,"../scatter/attributes":529}],492:[function(_dereq_,module,exports){
89038
+ },{"../../components/colorscale/attributes":263,"../../lib/extend":380,"../../plots/attributes":434,"../../plots/cartesian/axis_format_attributes":441,"../../plots/font_attributes":469,"../../plots/template_attributes":480,"../scatter/attributes":529}],492:[function(_dereq_,module,exports){
88722
89039
  'use strict';
88723
89040
 
88724
89041
  var Registry = _dereq_('../../registry');
@@ -89970,8 +90287,9 @@ var getBinSpanLabelRound = _dereq_('./bin_label_vals');
89970
90287
  function calc(gd, trace) {
89971
90288
  var pos = [];
89972
90289
  var size = [];
89973
- var pa = Axes.getFromId(gd, trace.orientation === 'h' ? trace.yaxis : trace.xaxis);
89974
- var mainData = trace.orientation === 'h' ? 'y' : 'x';
90290
+ var isHorizontal = trace.orientation === 'h';
90291
+ var pa = Axes.getFromId(gd, isHorizontal ? trace.yaxis : trace.xaxis);
90292
+ var mainData = isHorizontal ? 'y' : 'x';
89975
90293
  var counterData = {x: 'y', y: 'x'}[mainData];
89976
90294
  var calendar = trace[mainData + 'calendar'];
89977
90295
  var cumulativeSpec = trace.cumulative;
@@ -100592,7 +100910,7 @@ function getSortFunc(opts, d2c) {
100592
100910
  'use strict';
100593
100911
 
100594
100912
  // package version injected by `npm run preprocess`
100595
- exports.version = '2.7.0';
100913
+ exports.version = '2.8.3';
100596
100914
 
100597
100915
  },{}],588:[function(_dereq_,module,exports){
100598
100916
  (function (global){(function (){