plotly.js 2.6.3 → 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +3 -3
  3. package/dist/README.md +26 -26
  4. package/dist/plot-schema.json +1015 -407
  5. package/dist/plotly-basic.js +533 -197
  6. package/dist/plotly-basic.min.js +4 -4
  7. package/dist/plotly-cartesian.js +996 -343
  8. package/dist/plotly-cartesian.min.js +3 -3
  9. package/dist/plotly-finance.js +583 -199
  10. package/dist/plotly-finance.min.js +4 -4
  11. package/dist/plotly-geo-assets.js +2 -2
  12. package/dist/plotly-geo.js +529 -195
  13. package/dist/plotly-geo.min.js +4 -4
  14. package/dist/plotly-gl2d.js +545 -196
  15. package/dist/plotly-gl2d.min.js +2 -2
  16. package/dist/plotly-gl3d.js +529 -195
  17. package/dist/plotly-gl3d.min.js +8 -8
  18. package/dist/plotly-mapbox.js +535 -198
  19. package/dist/plotly-mapbox.min.js +2 -2
  20. package/dist/plotly-strict.js +1220 -564
  21. package/dist/plotly-strict.min.js +3 -3
  22. package/dist/plotly-with-meta.js +1312 -626
  23. package/dist/plotly.js +1274 -618
  24. package/dist/plotly.min.js +10 -10
  25. package/package.json +9 -9
  26. package/src/components/colorbar/attributes.js +29 -20
  27. package/src/components/colorbar/defaults.js +30 -8
  28. package/src/components/colorbar/draw.js +374 -128
  29. package/src/components/drawing/index.js +6 -3
  30. package/src/components/fx/hover.js +5 -2
  31. package/src/components/fx/hoverlabel_defaults.js +4 -2
  32. package/src/components/fx/layout_attributes.js +14 -4
  33. package/src/components/fx/layout_defaults.js +2 -0
  34. package/src/components/legend/attributes.js +7 -0
  35. package/src/components/legend/defaults.js +24 -7
  36. package/src/components/titles/index.js +8 -2
  37. package/src/plot_api/plot_api.js +38 -9
  38. package/src/plots/font_attributes.js +3 -0
  39. package/src/plots/layout_attributes.js +1 -0
  40. package/src/plots/mapbox/mapbox.js +6 -3
  41. package/src/plots/plots.js +7 -15
  42. package/src/traces/bar/plot.js +1 -1
  43. package/src/traces/contour/attributes.js +12 -0
  44. package/src/traces/contour/defaults.js +9 -1
  45. package/src/traces/heatmap/attributes.js +16 -0
  46. package/src/traces/heatmap/defaults.js +2 -0
  47. package/src/traces/heatmap/label_defaults.js +13 -0
  48. package/src/traces/heatmap/plot.js +205 -4
  49. package/src/traces/histogram/attributes.js +40 -0
  50. package/src/traces/histogram/defaults.js +11 -0
  51. package/src/traces/histogram2d/attributes.js +8 -0
  52. package/src/traces/histogram2d/defaults.js +4 -0
  53. package/src/traces/histogram2dcontour/attributes.js +3 -1
  54. package/src/traces/histogram2dcontour/defaults.js +8 -1
  55. package/src/traces/pie/calc.js +3 -1
  56. package/src/version.js +1 -1
  57. package/tasks/test_mock.js +1 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * plotly.js (gl2d) v2.6.3
2
+ * plotly.js (gl2d) v2.8.1
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
+ );
35504
+
35505
+ var xRatio = {center: 0.5, right: 1}[xanchor] || 0;
35506
+ var yRatio = {top: 1, middle: 0.5}[yanchor] || 0;
35483
35507
 
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));
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
+ );
35500
35538
 
35501
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
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
+ }
35546
+
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
+ }
35767
35920
  }
35768
- innerThickness = Math.max(innerThickness, titleWidth);
35921
+
35922
+ if(rightSideHorizontal) {
35923
+ titleEl.attr('transform', strTranslate(titleWidth / 2 + titleFontSize / 2, 0));
35924
+
35925
+ titleWidth *= 2;
35926
+ }
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,
@@ -38433,7 +38700,7 @@ var TEXTOFFSETSIGN = {
38433
38700
  start: 1, end: -1, middle: 0, bottom: 1, top: -1
38434
38701
  };
38435
38702
 
38436
- function textPointPosition(s, textPosition, fontSize, markerRadius) {
38703
+ function textPointPosition(s, textPosition, fontSize, markerRadius, dontTouchParent) {
38437
38704
  var group = d3.select(s.node().parentNode);
38438
38705
 
38439
38706
  var v = textPosition.indexOf('top') !== -1 ?
@@ -38455,7 +38722,9 @@ function textPointPosition(s, textPosition, fontSize, markerRadius) {
38455
38722
 
38456
38723
  // fix the overall text group position
38457
38724
  s.attr('text-anchor', h);
38458
- group.attr('transform', strTranslate(dx, dy));
38725
+ if(!dontTouchParent) {
38726
+ group.attr('transform', strTranslate(dx, dy));
38727
+ }
38459
38728
  }
38460
38729
 
38461
38730
  function extracTextFontSize(d, trace) {
@@ -38525,7 +38794,8 @@ drawing.selectedTextStyle = function(s, trace) {
38525
38794
  var fontSize = extracTextFontSize(d, trace);
38526
38795
 
38527
38796
  Color.fill(tx, tc);
38528
- textPointPosition(tx, tp, fontSize, d.mrc2 || d.mrc);
38797
+ var dontTouchParent = Registry.traceIs(trace, 'bar-like');
38798
+ textPointPosition(tx, tp, fontSize, d.mrc2 || d.mrc, dontTouchParent);
38529
38799
  });
38530
38800
  };
38531
38801
 
@@ -41581,7 +41851,9 @@ function createHoverText(hoverData, opts) {
41581
41851
  orientation: 'v'
41582
41852
  }
41583
41853
  };
41584
- var mockLayoutOut = {};
41854
+ var mockLayoutOut = {
41855
+ font: font
41856
+ };
41585
41857
  legendSupplyDefaults(mockLayoutIn, mockLayoutOut, gd._fullData);
41586
41858
  var mockLegend = mockLayoutOut.legend;
41587
41859
 
@@ -41622,7 +41894,8 @@ function createHoverText(hoverData, opts) {
41622
41894
 
41623
41895
  // Draw unified hover label
41624
41896
  mockLegend._inHover = true;
41625
- mockLegend._groupTitleFont = font;
41897
+ mockLegend._groupTitleFont = hoverlabel.grouptitlefont;
41898
+
41626
41899
  legendDraw(gd, mockLegend);
41627
41900
 
41628
41901
  // Position the hover
@@ -42624,9 +42897,11 @@ var isUnifiedHover = _dereq_('./helpers').isUnifiedHover;
42624
42897
  module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts) {
42625
42898
  opts = opts || {};
42626
42899
 
42900
+ var hasLegend = contOut.legend;
42901
+
42627
42902
  function inheritFontAttr(attr) {
42628
42903
  if(!opts.font[attr]) {
42629
- opts.font[attr] = contOut.legend ? contOut.legend.font[attr] : contOut.font[attr];
42904
+ opts.font[attr] = hasLegend ? contOut.legend.font[attr] : contOut.font[attr];
42630
42905
  }
42631
42906
  }
42632
42907
 
@@ -42637,7 +42912,7 @@ module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts
42637
42912
  inheritFontAttr('family');
42638
42913
  inheritFontAttr('color');
42639
42914
 
42640
- if(contOut.legend) {
42915
+ if(hasLegend) {
42641
42916
  if(!opts.bgcolor) opts.bgcolor = Color.combine(contOut.legend.bgcolor, contOut.paper_bgcolor);
42642
42917
  if(!opts.bordercolor) opts.bordercolor = contOut.legend.bordercolor;
42643
42918
  } else {
@@ -42746,11 +43021,13 @@ function castHoverinfo(trace, fullLayout, ptNumber) {
42746
43021
 
42747
43022
  var constants = _dereq_('./constants');
42748
43023
 
42749
- var fontAttrs = _dereq_('../../plots/font_attributes')({
43024
+ var fontAttrs = _dereq_('../../plots/font_attributes');
43025
+
43026
+ var font = fontAttrs({
42750
43027
  editType: 'none',
42751
43028
  });
42752
- fontAttrs.family.dflt = constants.HOVERFONT;
42753
- fontAttrs.size.dflt = constants.HOVERFONTSIZE;
43029
+ font.family.dflt = constants.HOVERFONT;
43030
+ font.size.dflt = constants.HOVERFONTSIZE;
42754
43031
 
42755
43032
  module.exports = {
42756
43033
  clickmode: {
@@ -42806,7 +43083,10 @@ module.exports = {
42806
43083
  valType: 'color',
42807
43084
  editType: 'none',
42808
43085
  },
42809
- font: fontAttrs,
43086
+ font: font,
43087
+ grouptitlefont: fontAttrs({
43088
+ editType: 'none',
43089
+ }),
42810
43090
  align: {
42811
43091
  valType: 'enumerated',
42812
43092
  values: ['left', 'right', 'auto'],
@@ -42819,6 +43099,7 @@ module.exports = {
42819
43099
  dflt: 15,
42820
43100
  editType: 'none',
42821
43101
  },
43102
+
42822
43103
  editType: 'none'
42823
43104
  },
42824
43105
  selectdirection: {
@@ -42866,6 +43147,8 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut) {
42866
43147
  }
42867
43148
 
42868
43149
  handleHoverLabelDefaults(layoutIn, layoutOut, coerce);
43150
+
43151
+ Lib.coerceFont(coerce, 'hoverlabel.grouptitlefont', layoutOut.hoverlabel.font);
42869
43152
  };
42870
43153
 
42871
43154
  },{"../../lib":388,"./hoverlabel_defaults":294,"./hovermode_defaults":295,"./layout_attributes":297}],299:[function(_dereq_,module,exports){
@@ -43749,6 +44032,9 @@ module.exports = {
43749
44032
  font: fontAttrs({
43750
44033
  editType: 'legend',
43751
44034
  }),
44035
+ grouptitlefont: fontAttrs({
44036
+ editType: 'legend',
44037
+ }),
43752
44038
  orientation: {
43753
44039
  valType: 'enumerated',
43754
44040
  values: ['v', 'h'],
@@ -43872,6 +44158,7 @@ var Registry = _dereq_('../../registry');
43872
44158
  var Lib = _dereq_('../../lib');
43873
44159
  var Template = _dereq_('../../plot_api/plot_template');
43874
44160
 
44161
+ var plotsAttrs = _dereq_('../../plots/attributes');
43875
44162
  var attributes = _dereq_('./attributes');
43876
44163
  var basePlotLayoutAttributes = _dereq_('../../plots/layout_attributes');
43877
44164
  var helpers = _dereq_('./helpers');
@@ -43879,13 +44166,30 @@ var helpers = _dereq_('./helpers');
43879
44166
 
43880
44167
  module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
43881
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
+ }));
43882
44186
 
43883
44187
  var legendTraceCount = 0;
43884
44188
  var legendReallyHasATrace = false;
43885
44189
  var defaultOrder = 'normal';
43886
44190
 
43887
44191
  for(var i = 0; i < fullData.length; i++) {
43888
- var trace = fullData[i];
44192
+ trace = fullData[i];
43889
44193
 
43890
44194
  if(!trace.visible) continue;
43891
44195
 
@@ -43912,6 +44216,8 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
43912
44216
  legendTraceCount++;
43913
44217
  }
43914
44218
  }
44219
+
44220
+ Lib.coerceFont(traceCoerce, 'legendgrouptitle.font', grouptitlefont);
43915
44221
  }
43916
44222
 
43917
44223
  if((Registry.traceIs(trace, 'bar') && layoutOut.barmode === 'stack') ||
@@ -43930,13 +44236,10 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
43930
44236
  basePlotLayoutAttributes, 'showlegend',
43931
44237
  legendReallyHasATrace && legendTraceCount > 1);
43932
44238
 
43933
- if(showLegend === false && !containerIn.uirevision) return;
44239
+ // delete legend
44240
+ if(showLegend === false) layoutOut.legend = undefined;
43934
44241
 
43935
- var containerOut = Template.newContainer(layoutOut, 'legend');
43936
-
43937
- function coerce(attr, dflt) {
43938
- return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
43939
- }
44242
+ if(showLegend === false && !containerIn.uirevision) return;
43940
44243
 
43941
44244
  coerce('uirevision', layoutOut.uirevision);
43942
44245
 
@@ -43998,7 +44301,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
43998
44301
  }
43999
44302
  };
44000
44303
 
44001
- },{"../../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){
44002
44305
  'use strict';
44003
44306
 
44004
44307
  var d3 = _dereq_('@plotly/d3');
@@ -52450,8 +52753,10 @@ function draw(gd, titleClass, options) {
52450
52753
 
52451
52754
  var elShouldExist = txt || editable;
52452
52755
 
52756
+ var hColorbarMoveTitle;
52453
52757
  if(!group) {
52454
52758
  group = Lib.ensureSingle(fullLayout._infolayer, 'g', 'g-' + titleClass);
52759
+ hColorbarMoveTitle = fullLayout._hColorbarMoveTitle;
52455
52760
  }
52456
52761
 
52457
52762
  var el = group.selectAll('text')
@@ -52475,13 +52780,17 @@ function draw(gd, titleClass, options) {
52475
52780
  function drawTitle(titleEl) {
52476
52781
  var transformVal;
52477
52782
 
52783
+ if(!transform && hColorbarMoveTitle) {
52784
+ transform = {};
52785
+ }
52786
+
52478
52787
  if(transform) {
52479
52788
  transformVal = '';
52480
52789
  if(transform.rotate) {
52481
52790
  transformVal += 'rotate(' + [transform.rotate, attributes.x, attributes.y] + ')';
52482
52791
  }
52483
- if(transform.offset) {
52484
- transformVal += strTranslate(0, transform.offset);
52792
+ if(transform.offset || hColorbarMoveTitle) {
52793
+ transformVal += strTranslate(0, (transform.offset || 0) - (hColorbarMoveTitle || 0));
52485
52794
  }
52486
52795
  } else {
52487
52796
  transformVal = null;
@@ -64193,7 +64502,7 @@ function cleanDeprecatedAttributeKeys(aobj) {
64193
64502
  if((key === 'title' || oldAxisTitleRegex.test(key) || colorbarRegex.test(key)) &&
64194
64503
  (typeof value === 'string' || typeof value === 'number')) {
64195
64504
  replace(key, key.replace('title', 'title.text'));
64196
- } else if(key.indexOf('titlefont') > -1) {
64505
+ } else if(key.indexOf('titlefont') > -1 && key.indexOf('grouptitlefont') === -1) {
64197
64506
  replace(key, key.replace('titlefont', 'title.font'));
64198
64507
  } else if(key.indexOf('titleposition') > -1) {
64199
64508
  replace(key, key.replace('titleposition', 'title.position'));
@@ -64870,7 +65179,8 @@ function findUIPattern(key, patternSpecs) {
64870
65179
  var spec = patternSpecs[i];
64871
65180
  var match = key.match(spec.pattern);
64872
65181
  if(match) {
64873
- return {head: match[1], attr: spec.attr};
65182
+ var head = match[1] || '';
65183
+ return {head: head, tail: key.substr(head.length + 1), attr: spec.attr};
64874
65184
  }
64875
65185
  }
64876
65186
  }
@@ -64922,26 +65232,54 @@ function valsMatch(v1, v2) {
64922
65232
 
64923
65233
  function applyUIRevisions(data, layout, oldFullData, oldFullLayout) {
64924
65234
  var layoutPreGUI = oldFullLayout._preGUI;
64925
- var key, revAttr, oldRev, newRev, match, preGUIVal, newNP, newVal;
65235
+ var key, revAttr, oldRev, newRev, match, preGUIVal, newNP, newVal, head, tail;
64926
65236
  var bothInheritAutorange = [];
65237
+ var newAutorangeIn = {};
64927
65238
  var newRangeAccepted = {};
64928
65239
  for(key in layoutPreGUI) {
64929
65240
  match = findUIPattern(key, layoutUIControlPatterns);
64930
65241
  if(match) {
64931
- revAttr = match.attr || (match.head + '.uirevision');
65242
+ head = match.head;
65243
+ tail = match.tail;
65244
+ revAttr = match.attr || (head + '.uirevision');
64932
65245
  oldRev = nestedProperty(oldFullLayout, revAttr).get();
64933
65246
  newRev = oldRev && getNewRev(revAttr, layout);
65247
+
64934
65248
  if(newRev && (newRev === oldRev)) {
64935
65249
  preGUIVal = layoutPreGUI[key];
64936
65250
  if(preGUIVal === null) preGUIVal = undefined;
64937
65251
  newNP = nestedProperty(layout, key);
64938
65252
  newVal = newNP.get();
65253
+
64939
65254
  if(valsMatch(newVal, preGUIVal)) {
64940
- if(newVal === undefined && key.substr(key.length - 9) === 'autorange') {
64941
- bothInheritAutorange.push(key.substr(0, key.length - 10));
65255
+ if(newVal === undefined && tail === 'autorange') {
65256
+ bothInheritAutorange.push(head);
64942
65257
  }
64943
65258
  newNP.set(undefinedToNull(nestedProperty(oldFullLayout, key).get()));
64944
65259
  continue;
65260
+ } else if(tail === 'autorange' || tail.substr(0, 6) === 'range[') {
65261
+ // Special case for (auto)range since we push it back into the layout
65262
+ // so all null should be treated equivalently to autorange: true with any range
65263
+ var pre0 = layoutPreGUI[head + '.range[0]'];
65264
+ var pre1 = layoutPreGUI[head + '.range[1]'];
65265
+ var preAuto = layoutPreGUI[head + '.autorange'];
65266
+ if(preAuto || (preAuto === null && pre0 === null && pre1 === null)) {
65267
+ // Only read the input layout once and stash the result,
65268
+ // so we get it before we start modifying it
65269
+ if(!(head in newAutorangeIn)) {
65270
+ var newContainer = nestedProperty(layout, head).get();
65271
+ newAutorangeIn[head] = newContainer && (
65272
+ newContainer.autorange ||
65273
+ (newContainer.autorange !== false && (
65274
+ !newContainer.range || newContainer.range.length !== 2)
65275
+ )
65276
+ );
65277
+ }
65278
+ if(newAutorangeIn[head]) {
65279
+ newNP.set(undefinedToNull(nestedProperty(oldFullLayout, key).get()));
65280
+ continue;
65281
+ }
65282
+ }
64945
65283
  }
64946
65284
  }
64947
65285
  } else {
@@ -64952,12 +65290,12 @@ function applyUIRevisions(data, layout, oldFullData, oldFullLayout) {
64952
65290
  // so remove it from _preGUI for next time.
64953
65291
  delete layoutPreGUI[key];
64954
65292
 
64955
- if(key.substr(key.length - 8, 6) === 'range[') {
64956
- newRangeAccepted[key.substr(0, key.length - 9)] = 1;
65293
+ if(match && match.tail.substr(0, 6) === 'range[') {
65294
+ newRangeAccepted[match.head] = 1;
64957
65295
  }
64958
65296
  }
64959
65297
 
64960
- // Special logic for `autorange`, since it interacts with `range`:
65298
+ // More special logic for `autorange`, since it interacts with `range`:
64961
65299
  // If the new figure's matching `range` was kept, and `autorange`
64962
65300
  // wasn't supplied explicitly in either the original or the new figure,
64963
65301
  // we shouldn't alter that - but we may just have done that, so fix it.
@@ -82032,6 +82370,9 @@ module.exports = function(opts) {
82032
82370
  // TODO - that's uber hacky... better solution?
82033
82371
  };
82034
82372
 
82373
+ if(opts.autoSize) attrs.size.dflt = 'auto';
82374
+ if(opts.autoColor) attrs.color.dflt = 'auto';
82375
+
82035
82376
  if(opts.arrayOk) {
82036
82377
  attrs.family.arrayOk = true;
82037
82378
  attrs.size.arrayOk = true;
@@ -83765,6 +84106,7 @@ module.exports = {
83765
84106
  valType: 'boolean',
83766
84107
  editType: 'legend',
83767
84108
  },
84109
+
83768
84110
  colorway: {
83769
84111
  valType: 'colorlist',
83770
84112
  dflt: colorAttrs.defaults,
@@ -85177,13 +85519,7 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac
85177
85519
  );
85178
85520
 
85179
85521
  coerce('legendgroup');
85180
- var titleText = coerce('legendgrouptitle.text');
85181
- if(titleText) {
85182
- Lib.coerceFont(coerce, 'legendgrouptitle.font', Lib.extendFlat({}, layout.font, {
85183
- size: Math.round(layout.font.size * 1.1) // default to larger font size
85184
- }));
85185
- }
85186
-
85522
+ coerce('legendgrouptitle.text');
85187
85523
  coerce('legendrank');
85188
85524
 
85189
85525
  traceOut._dfltShowLegend = true;
@@ -85331,16 +85667,14 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut, formatObj) {
85331
85667
 
85332
85668
  coerce('autotypenumbers');
85333
85669
 
85334
- var globalFont = Lib.coerceFont(coerce, 'font');
85335
-
85336
- coerce('title.text', layoutOut._dfltTitle.plot);
85670
+ var font = Lib.coerceFont(coerce, 'font');
85671
+ var fontSize = font.size;
85337
85672
 
85338
- Lib.coerceFont(coerce, 'title.font', {
85339
- family: globalFont.family,
85340
- size: Math.round(globalFont.size * 1.4),
85341
- color: globalFont.color
85342
- });
85673
+ Lib.coerceFont(coerce, 'title.font', Lib.extendFlat({}, font, {
85674
+ size: Math.round(fontSize * 1.4)
85675
+ }));
85343
85676
 
85677
+ coerce('title.text', layoutOut._dfltTitle.plot);
85344
85678
  coerce('title.xref');
85345
85679
  coerce('title.yref');
85346
85680
  coerce('title.x');
@@ -88599,8 +88933,10 @@ module.exports = function arraysToCalcdata(cd, trace) {
88599
88933
 
88600
88934
  var scatterAttrs = _dereq_('../scatter/attributes');
88601
88935
  var baseAttrs = _dereq_('../../plots/attributes');
88936
+ var fontAttrs = _dereq_('../../plots/font_attributes');
88602
88937
  var axisHoverFormat = _dereq_('../../plots/cartesian/axis_format_attributes').axisHoverFormat;
88603
88938
  var hovertemplateAttrs = _dereq_('../../plots/template_attributes').hovertemplateAttrs;
88939
+ var texttemplateAttrs = _dereq_('../../plots/template_attributes').texttemplateAttrs;
88604
88940
  var colorScaleAttrs = _dereq_('../../components/colorscale/attributes');
88605
88941
 
88606
88942
  var extendFlat = _dereq_('../../lib/extend').extendFlat;
@@ -88679,6 +89015,19 @@ module.exports = extendFlat({
88679
89015
  zhoverformat: axisHoverFormat('z', 1),
88680
89016
 
88681
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
+
88682
89031
  showlegend: extendFlat({}, baseAttrs.showlegend, {dflt: false})
88683
89032
  }, {
88684
89033
  transforms: undefined
@@ -88686,7 +89035,7 @@ module.exports = extendFlat({
88686
89035
  colorScaleAttrs('', {cLetter: 'z', autoColorDflt: false})
88687
89036
  );
88688
89037
 
88689
- },{"../../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){
88690
89039
  'use strict';
88691
89040
 
88692
89041
  var Registry = _dereq_('../../registry');
@@ -100560,7 +100909,7 @@ function getSortFunc(opts, d2c) {
100560
100909
  'use strict';
100561
100910
 
100562
100911
  // package version injected by `npm run preprocess`
100563
- exports.version = '2.6.3';
100912
+ exports.version = '2.8.1';
100564
100913
 
100565
100914
  },{}],588:[function(_dereq_,module,exports){
100566
100915
  (function (global){(function (){