plotly.js 2.6.2 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +568 -225
  6. package/dist/plotly-basic.min.js +4 -4
  7. package/dist/plotly-cartesian.js +1029 -371
  8. package/dist/plotly-cartesian.min.js +3 -3
  9. package/dist/plotly-finance.js +618 -227
  10. package/dist/plotly-finance.min.js +4 -4
  11. package/dist/plotly-geo-assets.js +2 -2
  12. package/dist/plotly-geo.js +564 -223
  13. package/dist/plotly-geo.min.js +2 -2
  14. package/dist/plotly-gl2d.js +580 -224
  15. package/dist/plotly-gl2d.min.js +2 -2
  16. package/dist/plotly-gl3d.js +564 -223
  17. package/dist/plotly-gl3d.min.js +2 -2
  18. package/dist/plotly-mapbox.js +570 -226
  19. package/dist/plotly-mapbox.min.js +2 -2
  20. package/dist/plotly-strict.js +1253 -592
  21. package/dist/plotly-strict.min.js +3 -3
  22. package/dist/plotly-with-meta.js +1345 -654
  23. package/dist/plotly.js +1307 -646
  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 +398 -141
  29. package/src/components/drawing/index.js +6 -3
  30. package/src/components/fx/hover.js +16 -17
  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 +203 -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.2
2
+ * plotly.js (gl2d) v2.8.0
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,6 +35446,21 @@ function makeColorBarData(gd) {
35425
35446
  }
35426
35447
 
35427
35448
  function drawColorBar(g, opts, gd) {
35449
+ var isVertical = opts.orientation === 'v';
35450
+ var len = opts.len;
35451
+ var lenmode = opts.lenmode;
35452
+ var thickness = opts.thickness;
35453
+ var thicknessmode = opts.thicknessmode;
35454
+ var outlinewidth = opts.outlinewidth;
35455
+ var borderwidth = opts.borderwidth;
35456
+ var bgcolor = opts.bgcolor;
35457
+ var xanchor = opts.xanchor;
35458
+ var yanchor = opts.yanchor;
35459
+ var xpad = opts.xpad;
35460
+ var ypad = opts.ypad;
35461
+ var optsX = opts.x;
35462
+ var optsY = isVertical ? opts.y : 1 - opts.y;
35463
+
35428
35464
  var fullLayout = gd._fullLayout;
35429
35465
  var gs = fullLayout._size;
35430
35466
 
@@ -35454,42 +35490,64 @@ function drawColorBar(g, opts, gd) {
35454
35490
  // when the colorbar itself is pushing the margins.
35455
35491
  // but then the fractional size is calculated based on the
35456
35492
  // actual graph size, so that the axes will size correctly.
35457
- var thickPx = Math.round(opts.thickness * (opts.thicknessmode === 'fraction' ? gs.w : 1));
35458
- var thickFrac = thickPx / gs.w;
35459
- var lenPx = Math.round(opts.len * (opts.lenmode === 'fraction' ? gs.h : 1));
35460
- var lenFrac = lenPx / gs.h;
35461
- var xpadFrac = opts.xpad / gs.w;
35462
- var yExtraPx = (opts.borderwidth + opts.outlinewidth) / 2;
35463
- var ypadFrac = opts.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);
35464
35497
 
35465
35498
  // x positioning: do it initially just for left anchor,
35466
35499
  // then fix at the end (since we don't know the width yet)
35467
- var xLeft = Math.round(opts.x * gs.w + opts.xpad);
35468
- // for dragging... this is getting a little muddled...
35469
- var xLeftFrac = opts.x - thickFrac * ({center: 0.5, right: 1}[opts.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;
35470
35507
 
35471
- // y positioning we can do correctly from the start
35472
- var yBottomFrac = opts.y + lenFrac * (({top: -0.5, bottom: 0.5}[opts.yanchor] || 0) - 0.5);
35473
- var yBottomPx = Math.round(gs.h * (1 - yBottomFrac));
35474
- var yTopPx = yBottomPx - lenPx;
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
+ );
35475
35522
 
35476
35523
  // stash a few things for makeEditable
35477
35524
  opts._lenFrac = lenFrac;
35478
35525
  opts._thickFrac = thickFrac;
35479
- opts._xLeftFrac = xLeftFrac;
35480
- opts._yBottomFrac = yBottomFrac;
35526
+ opts._uFrac = uFrac;
35527
+ opts._vFrac = vFrac;
35481
35528
 
35482
35529
  // stash mocked axis for contour label formatting
35483
35530
  var ax = opts._axis = mockColorBarAxis(gd, opts, zrange);
35484
35531
 
35485
35532
  // position can't go in through supplyDefaults
35486
35533
  // because that restricts it to [0,1]
35487
- ax.position = opts.x + 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
+ }
35488
35546
 
35489
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
35547
+ if(!isVertical && !topOrBottom) {
35490
35548
  ax.title.side = titleSide;
35491
- ax.titlex = opts.x + xpadFrac;
35492
- ax.titley = yBottomFrac + (title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
35549
+ ax.titley = optsY + ypad / gs.h;
35550
+ ax.titlex = vFrac + xpad / gs.w; // right side
35493
35551
  }
35494
35552
 
35495
35553
  if(line.color && opts.tickmode === 'auto') {
@@ -35497,7 +35555,7 @@ function drawColorBar(g, opts, gd) {
35497
35555
  ax.tick0 = levelsIn.start;
35498
35556
  var dtick = levelsIn.size;
35499
35557
  // expand if too many contours, so we don't get too many ticks
35500
- var autoNtick = Lib.constrain((yBottomPx - yTopPx) / 50, 4, 15) + 1;
35558
+ var autoNtick = Lib.constrain(lenPx / 50, 4, 15) + 1;
35501
35559
  var dtFactor = (zrange[1] - zrange[0]) / ((opts.nticks || autoNtick) * dtick);
35502
35560
  if(dtFactor > 1) {
35503
35561
  var dtexp = Math.pow(10, Math.floor(Math.log(dtFactor) / Math.LN10));
@@ -35514,9 +35572,12 @@ function drawColorBar(g, opts, gd) {
35514
35572
 
35515
35573
  // set domain after init, because we may want to
35516
35574
  // allow it outside [0,1]
35517
- ax.domain = [
35518
- yBottomFrac + ypadFrac,
35519
- yBottomFrac + 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
35520
35581
  ];
35521
35582
 
35522
35583
  ax.setScale();
@@ -35526,9 +35587,13 @@ function drawColorBar(g, opts, gd) {
35526
35587
  var titleCont = g.select('.' + cn.cbtitleunshift)
35527
35588
  .attr('transform', strTranslate(-Math.round(gs.l), -Math.round(gs.t)));
35528
35589
 
35590
+ var ticklabelposition = ax.ticklabelposition;
35591
+ var titleFontSize = ax.title.font.size;
35592
+
35529
35593
  var axLayer = g.select('.' + cn.cbaxis);
35530
35594
  var titleEl;
35531
35595
  var titleHeight = 0;
35596
+ var titleWidth = 0;
35532
35597
 
35533
35598
  function drawTitle(titleClass, titleOpts) {
35534
35599
  var dfltTitleOpts = {
@@ -35553,58 +35618,102 @@ function drawColorBar(g, opts, gd) {
35553
35618
  }
35554
35619
 
35555
35620
  function drawDummyTitle() {
35556
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
35557
- // draw the title so we know how much room it needs
35558
- // when we squish the axis. This one only applies to
35559
- // top or bottom titles, not right side.
35560
- var x = gs.l + (opts.x + xpadFrac) * gs.w;
35561
- var fontSize = ax.title.font.size;
35562
- 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;
35563
35631
 
35564
35632
  if(titleSide === 'top') {
35565
- y = (1 - (yBottomFrac + lenFrac - ypadFrac)) * gs.h +
35566
- gs.t + 3 + fontSize * 0.75;
35567
- } else {
35568
- y = (1 - (yBottomFrac + ypadFrac)) * gs.h +
35569
- 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;
35570
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
+
35571
35647
  drawTitle(ax._id + 'title', {
35572
- attributes: {x: x, y: y, 'text-anchor': 'start'}
35648
+ attributes: {x: x, y: y, 'text-anchor': isVertical ? 'start' : 'middle'}
35573
35649
  });
35574
35650
  }
35575
35651
  }
35576
35652
 
35577
35653
  function drawCbTitle() {
35578
- if(['top', 'bottom'].indexOf(titleSide) === -1) {
35579
- var fontSize = ax.title.font.size;
35580
- var y = ax._offset + ax._length / 2;
35581
- var x = gs.l + (ax.position || 0) * gs.w + ((ax.side === 'right') ?
35582
- 10 + fontSize * ((ax.showticklabels ? 1 : 0.5)) :
35583
- -10 - fontSize * ((ax.showticklabels ? 0.5 : 0)));
35584
-
35585
- // the 'h' + is a hack to get around the fact that
35586
- // convertToTspans rotates any 'y...' class by 90 degrees.
35587
- // TODO: find a better way to control this.
35588
- 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', {
35589
35695
  avoid: {
35590
35696
  selection: d3.select(gd).selectAll('g.' + ax._id + 'tick'),
35591
35697
  side: titleSide,
35592
- offsetLeft: gs.l,
35593
- offsetTop: 0,
35594
- maxShift: fullLayout.width
35698
+ offsetTop: isVertical ? 0 : gs.t,
35699
+ offsetLeft: isVertical ? gs.l : 0,
35700
+ maxShift: isVertical ? fullLayout.width : fullLayout.height
35595
35701
  },
35596
35702
  attributes: {x: x, y: y, 'text-anchor': 'middle'},
35597
- transform: {rotate: '-90', offset: 0}
35703
+ transform: {rotate: isVertical ? -90 : 0, offset: 0}
35598
35704
  });
35599
35705
  }
35600
35706
  }
35601
35707
 
35602
35708
  function drawAxis() {
35603
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
35709
+ if(
35710
+ (!isVertical && !topOrBottom) ||
35711
+ (isVertical && topOrBottom)
35712
+ ) {
35604
35713
  // squish the axis top to make room for the title
35605
35714
  var titleGroup = g.select('.' + cn.cbtitle);
35606
35715
  var titleText = titleGroup.select('text');
35607
- var titleTrans = [-opts.outlinewidth / 2, opts.outlinewidth / 2];
35716
+ var titleTrans = [-outlinewidth / 2, outlinewidth / 2];
35608
35717
  var mathJaxNode = titleGroup
35609
35718
  .select('.h' + ax._id + 'title-math-group')
35610
35719
  .node();
@@ -35612,39 +35721,63 @@ function drawColorBar(g, opts, gd) {
35612
35721
  if(titleText.node()) {
35613
35722
  lineSize = parseInt(titleText.node().style.fontSize, 10) * LINE_SPACING;
35614
35723
  }
35724
+
35725
+ var bb;
35615
35726
  if(mathJaxNode) {
35616
- titleHeight = Drawing.bBox(mathJaxNode).height;
35727
+ bb = Drawing.bBox(mathJaxNode);
35728
+ titleWidth = bb.width;
35729
+ titleHeight = bb.height;
35617
35730
  if(titleHeight > lineSize) {
35618
35731
  // not entirely sure how mathjax is doing
35619
35732
  // vertical alignment, but this seems to work.
35620
35733
  titleTrans[1] -= (titleHeight - lineSize) / 2;
35621
35734
  }
35622
35735
  } else if(titleText.node() && !titleText.classed(cn.jsPlaceholder)) {
35623
- titleHeight = Drawing.bBox(titleText.node()).height;
35736
+ bb = Drawing.bBox(titleText.node());
35737
+ titleWidth = bb.width;
35738
+ titleHeight = bb.height;
35624
35739
  }
35625
- if(titleHeight) {
35626
- // buffer btwn colorbar and title
35627
- // TODO: configurable
35628
- titleHeight += 5;
35629
35740
 
35630
- if(titleSide === 'top') {
35631
- ax.domain[1] -= titleHeight / gs.h;
35632
- titleTrans[1] *= -1;
35633
- } else {
35634
- ax.domain[0] += titleHeight / gs.h;
35635
- var nlines = svgTextUtils.lineCount(titleText);
35636
- 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();
35637
35758
  }
35759
+ } else { // horizontal colorbars
35760
+ if(titleWidth) {
35761
+ if(titleSide === 'right') {
35762
+ ax.domain[0] += (titleWidth + titleFontSize / 2) / gs.w;
35763
+ }
35638
35764
 
35639
- titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
35640
- ax.setScale();
35765
+ titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
35766
+ ax.setScale();
35767
+ }
35641
35768
  }
35642
35769
  }
35643
35770
 
35644
35771
  g.selectAll('.' + cn.cbfills + ',.' + cn.cblines)
35645
- .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
+ );
35646
35776
 
35647
- 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
+ );
35648
35781
 
35649
35782
  var fills = g.select('.' + cn.cbfills)
35650
35783
  .selectAll('rect.' + cn.cbfill)
@@ -35670,20 +35803,22 @@ function drawColorBar(g, opts, gd) {
35670
35803
 
35671
35804
  // offset the side adjoining the next rectangle so they
35672
35805
  // overlap, to prevent antialiasing gaps
35673
- z[1] = Lib.constrain(z[1] + (z[1] > z[0]) ? 1 : -1, zBounds[0], zBounds[1]);
35674
-
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
+ } */
35675
35811
 
35676
35812
  // Colorbar cannot currently support opacities so we
35677
35813
  // use an opaque fill even when alpha channels present
35678
- var fillEl = d3.select(this).attr({
35679
- x: xLeft,
35680
- width: Math.max(thickPx, 2),
35681
- y: d3.min(z),
35682
- height: Math.max(d3.max(z) - d3.min(z), 2),
35683
- });
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));
35684
35819
 
35685
35820
  if(opts._fillgradient) {
35686
- Drawing.gradient(fillEl, gd, opts._id, 'vertical', opts._fillgradient, 'fill');
35821
+ Drawing.gradient(fillEl, gd, opts._id, isVertical ? 'vertical' : 'horizontalreversed', opts._fillgradient, 'fill');
35687
35822
  } else {
35688
35823
  // tinycolor can't handle exponents and
35689
35824
  // at this scale, removing it makes no difference.
@@ -35699,17 +35834,23 @@ function drawColorBar(g, opts, gd) {
35699
35834
  .classed(cn.cbline, true);
35700
35835
  lines.exit().remove();
35701
35836
  lines.each(function(d) {
35837
+ var a = uPx;
35838
+ var b = (Math.round(ax.c2p(d)) + (line.width / 2) % 1);
35839
+
35702
35840
  d3.select(this)
35703
- .attr('d', 'M' + xLeft + ',' +
35704
- (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
+ )
35705
35846
  .call(Drawing.lineGroupStyle, line.width, lineColormap(d), line.dash);
35706
35847
  });
35707
35848
 
35708
35849
  // force full redraw of labels and ticks
35709
35850
  axLayer.selectAll('g.' + ax._id + 'tick,path').remove();
35710
35851
 
35711
- var shift = xLeft + thickPx +
35712
- (opts.outlinewidth || 0) / 2 - (opts.ticks === 'outside' ? 1 : 0);
35852
+ var shift = uPx + thickPx +
35853
+ (outlinewidth || 0) / 2 - (opts.ticks === 'outside' ? 1 : 0);
35713
35854
 
35714
35855
  var vals = Axes.calcTicks(ax);
35715
35856
  var tickSign = Axes.getTickSigns(ax)[2];
@@ -35734,83 +35875,211 @@ function drawColorBar(g, opts, gd) {
35734
35875
  // TODO: why are we redrawing multiple times now with this?
35735
35876
  // I guess autoMargin doesn't like being post-promise?
35736
35877
  function positionCB() {
35737
- var innerWidth = thickPx + opts.outlinewidth / 2;
35738
- if(ax.ticklabelposition.indexOf('inside') === -1) {
35739
- innerWidth += Drawing.bBox(axLayer.node()).width;
35878
+ var bb;
35879
+ var innerThickness = thickPx + outlinewidth / 2;
35880
+ if(ticklabelposition.indexOf('inside') === -1) {
35881
+ bb = Drawing.bBox(axLayer.node());
35882
+ innerThickness += isVertical ? bb.width : bb.height;
35740
35883
  }
35741
35884
 
35742
35885
  titleEl = titleCont.select('text');
35743
35886
 
35887
+ var titleWidth = 0;
35888
+
35889
+ var topSideVertical = isVertical && titleSide === 'top';
35890
+ var rightSideHorizontal = !isVertical && titleSide === 'right';
35891
+
35892
+ var moveY = 0;
35893
+
35744
35894
  if(titleEl.node() && !titleEl.classed(cn.jsPlaceholder)) {
35895
+ var _titleHeight;
35896
+
35745
35897
  var mathJaxNode = titleCont.select('.h' + ax._id + 'title-math-group').node();
35746
- var titleWidth;
35747
- if(mathJaxNode && ['top', 'bottom'].indexOf(titleSide) !== -1) {
35748
- 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;
35749
35905
  } else {
35750
35906
  // note: the formula below works for all title sides,
35751
35907
  // (except for top/bottom mathjax, above)
35752
35908
  // but the weird gs.l is because the titleunshift
35753
35909
  // transform gets removed by Drawing.bBox
35754
- titleWidth = Drawing.bBox(titleCont.node()).right - xLeft - 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;
35755
35926
  }
35756
- innerWidth = Math.max(innerWidth, titleWidth);
35927
+
35928
+ innerThickness = Math.max(innerThickness,
35929
+ isVertical ? titleWidth : _titleHeight
35930
+ );
35757
35931
  }
35758
35932
 
35759
- var outerwidth = 2 * opts.xpad + innerWidth + opts.borderwidth + opts.outlinewidth / 2;
35760
- var outerheight = yBottomPx - yTopPx;
35933
+ var outerThickness = (isVertical ?
35934
+ xpad :
35935
+ ypad
35936
+ ) * 2 + innerThickness + borderwidth + outlinewidth / 2;
35761
35937
 
35762
- g.select('.' + cn.cbbg).attr({
35763
- x: xLeft - opts.xpad - (opts.borderwidth + opts.outlinewidth) / 2,
35764
- y: yTopPx - yExtraPx,
35765
- width: Math.max(outerwidth, 2),
35766
- height: Math.max(outerheight + 2 * yExtraPx, 2)
35767
- })
35768
- .call(Color.fill, opts.bgcolor)
35769
- .call(Color.stroke, opts.bordercolor)
35770
- .style('stroke-width', opts.borderwidth);
35938
+ var hColorbarMoveTitle = 0;
35939
+ if(!isVertical && title.text && yanchor === 'bottom' && optsY <= 0) {
35940
+ hColorbarMoveTitle = outerThickness / 2;
35771
35941
 
35772
- g.selectAll('.' + cn.cboutline).attr({
35773
- x: xLeft,
35774
- y: yTopPx + opts.ypad + (titleSide === 'top' ? titleHeight : 0),
35775
- width: Math.max(thickPx, 2),
35776
- height: Math.max(outerheight - 2 * opts.ypad - titleHeight, 2)
35777
- })
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)
35956
+ .call(Color.stroke, opts.bordercolor)
35957
+ .style('stroke-width', borderwidth);
35958
+
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))
35778
35969
  .call(Color.stroke, opts.outlinecolor)
35779
35970
  .style({
35780
35971
  fill: 'none',
35781
- 'stroke-width': opts.outlinewidth
35972
+ 'stroke-width': outlinewidth
35782
35973
  });
35783
35974
 
35784
- // fix positioning for xanchor!='left'
35785
- var xoffset = ({center: 0.5, right: 1}[opts.xanchor] || 0) * outerwidth;
35786
- 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
+ }
35787
36032
 
35788
36033
  // auto margin adjustment
35789
36034
  var marginOpts = {};
35790
- var tFrac = FROM_TL[opts.yanchor];
35791
- var bFrac = FROM_BR[opts.yanchor];
35792
- if(opts.lenmode === 'pixels') {
35793
- marginOpts.y = opts.y;
35794
- marginOpts.t = outerheight * tFrac;
35795
- marginOpts.b = outerheight * bFrac;
35796
- } else {
35797
- marginOpts.t = marginOpts.b = 0;
35798
- marginOpts.yt = opts.y + opts.len * tFrac;
35799
- marginOpts.yb = opts.y - opts.len * bFrac;
35800
- }
36035
+ var lFrac = FROM_TL[xanchor];
36036
+ var rFrac = FROM_BR[xanchor];
36037
+ var tFrac = FROM_TL[yanchor];
36038
+ var bFrac = FROM_BR[yanchor];
35801
36039
 
35802
- var lFrac = FROM_TL[opts.xanchor];
35803
- var rFrac = FROM_BR[opts.xanchor];
35804
- if(opts.thicknessmode === 'pixels') {
35805
- marginOpts.x = opts.x;
35806
- marginOpts.l = outerwidth * lFrac;
35807
- marginOpts.r = outerwidth * rFrac;
35808
- } else {
35809
- var extraThickness = outerwidth - thickPx;
35810
- marginOpts.l = extraThickness * lFrac;
35811
- marginOpts.r = extraThickness * rFrac;
35812
- marginOpts.xl = opts.x - opts.thickness * lFrac;
35813
- marginOpts.xr = opts.x + opts.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
+ }
35814
36083
  }
35815
36084
 
35816
36085
  Plots.autoMargin(gd, opts._id, marginOpts);
@@ -35827,6 +36096,7 @@ function drawColorBar(g, opts, gd) {
35827
36096
  }
35828
36097
 
35829
36098
  function makeEditable(g, opts, gd) {
36099
+ var isVertical = opts.orientation === 'v';
35830
36100
  var fullLayout = gd._fullLayout;
35831
36101
  var gs = fullLayout._size;
35832
36102
  var t0, xf, yf;
@@ -35841,9 +36111,13 @@ function makeEditable(g, opts, gd) {
35841
36111
  moveFn: function(dx, dy) {
35842
36112
  g.attr('transform', t0 + strTranslate(dx, dy));
35843
36113
 
35844
- xf = dragElement.align(opts._xLeftFrac + (dx / gs.w), opts._thickFrac,
36114
+ xf = dragElement.align(
36115
+ (isVertical ? opts._uFrac : opts._vFrac) + (dx / gs.w),
36116
+ isVertical ? opts._thickFrac : opts._lenFrac,
35845
36117
  0, 1, opts.xanchor);
35846
- yf = dragElement.align(opts._yBottomFrac - (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,
35847
36121
  0, 1, opts.yanchor);
35848
36122
 
35849
36123
  var csr = dragElement.getCursor(xf, yf, opts.xanchor, opts.yanchor);
@@ -35920,6 +36194,8 @@ function calcLevels(gd, opts, zrange) {
35920
36194
  function mockColorBarAxis(gd, opts, zrange) {
35921
36195
  var fullLayout = gd._fullLayout;
35922
36196
 
36197
+ var isVertical = opts.orientation === 'v';
36198
+
35923
36199
  var cbAxisIn = {
35924
36200
  type: 'linear',
35925
36201
  range: zrange,
@@ -35950,17 +36226,19 @@ function mockColorBarAxis(gd, opts, zrange) {
35950
36226
  title: opts.title,
35951
36227
  showline: true,
35952
36228
  anchor: 'free',
35953
- side: 'right',
36229
+ side: isVertical ? 'right' : 'bottom',
35954
36230
  position: 1
35955
36231
  };
35956
36232
 
36233
+ var letter = isVertical ? 'y' : 'x';
36234
+
35957
36235
  var cbAxisOut = {
35958
36236
  type: 'linear',
35959
- _id: 'y' + opts._id
36237
+ _id: letter + opts._id
35960
36238
  };
35961
36239
 
35962
36240
  var axisOptions = {
35963
- letter: 'y',
36241
+ letter: letter,
35964
36242
  font: fullLayout.font,
35965
36243
  noHover: true,
35966
36244
  noTickson: true,
@@ -38422,7 +38700,7 @@ var TEXTOFFSETSIGN = {
38422
38700
  start: 1, end: -1, middle: 0, bottom: 1, top: -1
38423
38701
  };
38424
38702
 
38425
- function textPointPosition(s, textPosition, fontSize, markerRadius) {
38703
+ function textPointPosition(s, textPosition, fontSize, markerRadius, dontTouchParent) {
38426
38704
  var group = d3.select(s.node().parentNode);
38427
38705
 
38428
38706
  var v = textPosition.indexOf('top') !== -1 ?
@@ -38444,7 +38722,9 @@ function textPointPosition(s, textPosition, fontSize, markerRadius) {
38444
38722
 
38445
38723
  // fix the overall text group position
38446
38724
  s.attr('text-anchor', h);
38447
- group.attr('transform', strTranslate(dx, dy));
38725
+ if(!dontTouchParent) {
38726
+ group.attr('transform', strTranslate(dx, dy));
38727
+ }
38448
38728
  }
38449
38729
 
38450
38730
  function extracTextFontSize(d, trace) {
@@ -38514,7 +38794,8 @@ drawing.selectedTextStyle = function(s, trace) {
38514
38794
  var fontSize = extracTextFontSize(d, trace);
38515
38795
 
38516
38796
  Color.fill(tx, tc);
38517
- 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);
38518
38799
  });
38519
38800
  };
38520
38801
 
@@ -40545,11 +40826,13 @@ var cartesianScatterPoints = {
40545
40826
  // The actual rendering is done by private function _hover.
40546
40827
  exports.hover = function hover(gd, evt, subplot, noHoverEvent) {
40547
40828
  gd = Lib.getGraphDiv(gd);
40548
-
40829
+ // The 'target' property changes when bubbling out of Shadow DOM.
40830
+ // Throttling can delay reading the target, so we save the current value.
40831
+ var eventTarget = evt.target;
40549
40832
  Lib.throttle(
40550
40833
  gd._fullLayout._uid + constants.HOVERID,
40551
40834
  constants.HOVERMINTIME,
40552
- function() { _hover(gd, evt, subplot, noHoverEvent); }
40835
+ function() { _hover(gd, evt, subplot, noHoverEvent, eventTarget); }
40553
40836
  );
40554
40837
  };
40555
40838
 
@@ -40714,7 +40997,7 @@ exports.loneHover = function loneHover(hoverItems, opts) {
40714
40997
  };
40715
40998
 
40716
40999
  // The actual implementation is here:
40717
- function _hover(gd, evt, subplot, noHoverEvent) {
41000
+ function _hover(gd, evt, subplot, noHoverEvent, eventTarget) {
40718
41001
  if(!subplot) subplot = 'xy';
40719
41002
 
40720
41003
  // if the user passed in an array of subplots,
@@ -40833,7 +41116,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
40833
41116
  // [x|y]px: the pixels (from top left) of the mouse location
40834
41117
  // on the currently selected plot area
40835
41118
  // add pointerX|Y property for drawing the spikes in spikesnap 'cursor' situation
40836
- var hasUserCalledHover = !evt.target;
41119
+ var hasUserCalledHover = !eventTarget;
40837
41120
  var xpx, ypx;
40838
41121
 
40839
41122
  if(hasUserCalledHover) {
@@ -40850,13 +41133,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
40850
41133
  return;
40851
41134
  }
40852
41135
 
40853
- // Discover event target, traversing open shadow roots.
40854
- var target = evt.composedPath && evt.composedPath()[0];
40855
- if(!target) {
40856
- // Fallback for browsers not supporting composedPath
40857
- target = evt.target;
40858
- }
40859
- var dbb = target.getBoundingClientRect();
41136
+ var dbb = eventTarget.getBoundingClientRect();
40860
41137
 
40861
41138
  xpx = evt.clientX - dbb.left;
40862
41139
  ypx = evt.clientY - dbb.top;
@@ -41304,15 +41581,15 @@ function _hover(gd, evt, subplot, noHoverEvent) {
41304
41581
  if(!helpers.isUnifiedHover(hovermode)) {
41305
41582
  hoverAvoidOverlaps(hoverLabels, rotateLabels ? 'xa' : 'ya', fullLayout);
41306
41583
  alignHoverText(hoverLabels, rotateLabels, fullLayout._invScaleX, fullLayout._invScaleY);
41307
- } // TODO: tagName hack is needed to appease geo.js's hack of using evt.target=true
41584
+ } // TODO: tagName hack is needed to appease geo.js's hack of using eventTarget=true
41308
41585
  // we should improve the "fx" API so other plots can use it without these hack.
41309
- if(evt.target && evt.target.tagName) {
41586
+ if(eventTarget && eventTarget.tagName) {
41310
41587
  var hasClickToShow = Registry.getComponentMethod('annotations', 'hasClickToShow')(gd, newhoverdata);
41311
- overrideCursor(d3.select(evt.target), hasClickToShow ? 'pointer' : '');
41588
+ overrideCursor(d3.select(eventTarget), hasClickToShow ? 'pointer' : '');
41312
41589
  }
41313
41590
 
41314
41591
  // don't emit events if called manually
41315
- if(!evt.target || noHoverEvent || !hoverChanged(gd, evt, oldhoverdata)) return;
41592
+ if(!eventTarget || noHoverEvent || !hoverChanged(gd, evt, oldhoverdata)) return;
41316
41593
 
41317
41594
  if(oldhoverdata) {
41318
41595
  gd.emit('plotly_unhover', {
@@ -41574,7 +41851,9 @@ function createHoverText(hoverData, opts) {
41574
41851
  orientation: 'v'
41575
41852
  }
41576
41853
  };
41577
- var mockLayoutOut = {};
41854
+ var mockLayoutOut = {
41855
+ font: font
41856
+ };
41578
41857
  legendSupplyDefaults(mockLayoutIn, mockLayoutOut, gd._fullData);
41579
41858
  var mockLegend = mockLayoutOut.legend;
41580
41859
 
@@ -41615,7 +41894,8 @@ function createHoverText(hoverData, opts) {
41615
41894
 
41616
41895
  // Draw unified hover label
41617
41896
  mockLegend._inHover = true;
41618
- mockLegend._groupTitleFont = font;
41897
+ mockLegend._groupTitleFont = hoverlabel.grouptitlefont;
41898
+
41619
41899
  legendDraw(gd, mockLegend);
41620
41900
 
41621
41901
  // Position the hover
@@ -42617,9 +42897,11 @@ var isUnifiedHover = _dereq_('./helpers').isUnifiedHover;
42617
42897
  module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts) {
42618
42898
  opts = opts || {};
42619
42899
 
42900
+ var hasLegend = contOut.legend;
42901
+
42620
42902
  function inheritFontAttr(attr) {
42621
42903
  if(!opts.font[attr]) {
42622
- opts.font[attr] = contOut.legend ? contOut.legend.font[attr] : contOut.font[attr];
42904
+ opts.font[attr] = hasLegend ? contOut.legend.font[attr] : contOut.font[attr];
42623
42905
  }
42624
42906
  }
42625
42907
 
@@ -42630,7 +42912,7 @@ module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts
42630
42912
  inheritFontAttr('family');
42631
42913
  inheritFontAttr('color');
42632
42914
 
42633
- if(contOut.legend) {
42915
+ if(hasLegend) {
42634
42916
  if(!opts.bgcolor) opts.bgcolor = Color.combine(contOut.legend.bgcolor, contOut.paper_bgcolor);
42635
42917
  if(!opts.bordercolor) opts.bordercolor = contOut.legend.bordercolor;
42636
42918
  } else {
@@ -42739,11 +43021,13 @@ function castHoverinfo(trace, fullLayout, ptNumber) {
42739
43021
 
42740
43022
  var constants = _dereq_('./constants');
42741
43023
 
42742
- var fontAttrs = _dereq_('../../plots/font_attributes')({
43024
+ var fontAttrs = _dereq_('../../plots/font_attributes');
43025
+
43026
+ var font = fontAttrs({
42743
43027
  editType: 'none',
42744
43028
  });
42745
- fontAttrs.family.dflt = constants.HOVERFONT;
42746
- fontAttrs.size.dflt = constants.HOVERFONTSIZE;
43029
+ font.family.dflt = constants.HOVERFONT;
43030
+ font.size.dflt = constants.HOVERFONTSIZE;
42747
43031
 
42748
43032
  module.exports = {
42749
43033
  clickmode: {
@@ -42799,7 +43083,10 @@ module.exports = {
42799
43083
  valType: 'color',
42800
43084
  editType: 'none',
42801
43085
  },
42802
- font: fontAttrs,
43086
+ font: font,
43087
+ grouptitlefont: fontAttrs({
43088
+ editType: 'none',
43089
+ }),
42803
43090
  align: {
42804
43091
  valType: 'enumerated',
42805
43092
  values: ['left', 'right', 'auto'],
@@ -42812,6 +43099,7 @@ module.exports = {
42812
43099
  dflt: 15,
42813
43100
  editType: 'none',
42814
43101
  },
43102
+
42815
43103
  editType: 'none'
42816
43104
  },
42817
43105
  selectdirection: {
@@ -42859,6 +43147,8 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut) {
42859
43147
  }
42860
43148
 
42861
43149
  handleHoverLabelDefaults(layoutIn, layoutOut, coerce);
43150
+
43151
+ Lib.coerceFont(coerce, 'hoverlabel.grouptitlefont', layoutOut.hoverlabel.font);
42862
43152
  };
42863
43153
 
42864
43154
  },{"../../lib":388,"./hoverlabel_defaults":294,"./hovermode_defaults":295,"./layout_attributes":297}],299:[function(_dereq_,module,exports){
@@ -43742,6 +44032,9 @@ module.exports = {
43742
44032
  font: fontAttrs({
43743
44033
  editType: 'legend',
43744
44034
  }),
44035
+ grouptitlefont: fontAttrs({
44036
+ editType: 'legend',
44037
+ }),
43745
44038
  orientation: {
43746
44039
  valType: 'enumerated',
43747
44040
  values: ['v', 'h'],
@@ -43865,6 +44158,7 @@ var Registry = _dereq_('../../registry');
43865
44158
  var Lib = _dereq_('../../lib');
43866
44159
  var Template = _dereq_('../../plot_api/plot_template');
43867
44160
 
44161
+ var plotsAttrs = _dereq_('../../plots/attributes');
43868
44162
  var attributes = _dereq_('./attributes');
43869
44163
  var basePlotLayoutAttributes = _dereq_('../../plots/layout_attributes');
43870
44164
  var helpers = _dereq_('./helpers');
@@ -43872,13 +44166,30 @@ var helpers = _dereq_('./helpers');
43872
44166
 
43873
44167
  module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
43874
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
+ }));
43875
44186
 
43876
44187
  var legendTraceCount = 0;
43877
44188
  var legendReallyHasATrace = false;
43878
44189
  var defaultOrder = 'normal';
43879
44190
 
43880
44191
  for(var i = 0; i < fullData.length; i++) {
43881
- var trace = fullData[i];
44192
+ trace = fullData[i];
43882
44193
 
43883
44194
  if(!trace.visible) continue;
43884
44195
 
@@ -43905,6 +44216,8 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
43905
44216
  legendTraceCount++;
43906
44217
  }
43907
44218
  }
44219
+
44220
+ Lib.coerceFont(traceCoerce, 'legendgrouptitle.font', grouptitlefont);
43908
44221
  }
43909
44222
 
43910
44223
  if((Registry.traceIs(trace, 'bar') && layoutOut.barmode === 'stack') ||
@@ -43923,13 +44236,10 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
43923
44236
  basePlotLayoutAttributes, 'showlegend',
43924
44237
  legendReallyHasATrace && legendTraceCount > 1);
43925
44238
 
43926
- if(showLegend === false && !containerIn.uirevision) return;
44239
+ // delete legend
44240
+ if(showLegend === false) layoutOut.legend = undefined;
43927
44241
 
43928
- var containerOut = Template.newContainer(layoutOut, 'legend');
43929
-
43930
- function coerce(attr, dflt) {
43931
- return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
43932
- }
44242
+ if(showLegend === false && !containerIn.uirevision) return;
43933
44243
 
43934
44244
  coerce('uirevision', layoutOut.uirevision);
43935
44245
 
@@ -43991,7 +44301,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
43991
44301
  }
43992
44302
  };
43993
44303
 
43994
- },{"../../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){
43995
44305
  'use strict';
43996
44306
 
43997
44307
  var d3 = _dereq_('@plotly/d3');
@@ -52443,8 +52753,10 @@ function draw(gd, titleClass, options) {
52443
52753
 
52444
52754
  var elShouldExist = txt || editable;
52445
52755
 
52756
+ var hColorbarMoveTitle;
52446
52757
  if(!group) {
52447
52758
  group = Lib.ensureSingle(fullLayout._infolayer, 'g', 'g-' + titleClass);
52759
+ hColorbarMoveTitle = fullLayout._hColorbarMoveTitle;
52448
52760
  }
52449
52761
 
52450
52762
  var el = group.selectAll('text')
@@ -52468,13 +52780,17 @@ function draw(gd, titleClass, options) {
52468
52780
  function drawTitle(titleEl) {
52469
52781
  var transformVal;
52470
52782
 
52783
+ if(!transform && hColorbarMoveTitle) {
52784
+ transform = {};
52785
+ }
52786
+
52471
52787
  if(transform) {
52472
52788
  transformVal = '';
52473
52789
  if(transform.rotate) {
52474
52790
  transformVal += 'rotate(' + [transform.rotate, attributes.x, attributes.y] + ')';
52475
52791
  }
52476
- if(transform.offset) {
52477
- transformVal += strTranslate(0, transform.offset);
52792
+ if(transform.offset || hColorbarMoveTitle) {
52793
+ transformVal += strTranslate(0, (transform.offset || 0) - (hColorbarMoveTitle || 0));
52478
52794
  }
52479
52795
  } else {
52480
52796
  transformVal = null;
@@ -64186,7 +64502,7 @@ function cleanDeprecatedAttributeKeys(aobj) {
64186
64502
  if((key === 'title' || oldAxisTitleRegex.test(key) || colorbarRegex.test(key)) &&
64187
64503
  (typeof value === 'string' || typeof value === 'number')) {
64188
64504
  replace(key, key.replace('title', 'title.text'));
64189
- } else if(key.indexOf('titlefont') > -1) {
64505
+ } else if(key.indexOf('titlefont') > -1 && key.indexOf('grouptitlefont') === -1) {
64190
64506
  replace(key, key.replace('titlefont', 'title.font'));
64191
64507
  } else if(key.indexOf('titleposition') > -1) {
64192
64508
  replace(key, key.replace('titleposition', 'title.position'));
@@ -64863,7 +65179,8 @@ function findUIPattern(key, patternSpecs) {
64863
65179
  var spec = patternSpecs[i];
64864
65180
  var match = key.match(spec.pattern);
64865
65181
  if(match) {
64866
- 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};
64867
65184
  }
64868
65185
  }
64869
65186
  }
@@ -64915,26 +65232,54 @@ function valsMatch(v1, v2) {
64915
65232
 
64916
65233
  function applyUIRevisions(data, layout, oldFullData, oldFullLayout) {
64917
65234
  var layoutPreGUI = oldFullLayout._preGUI;
64918
- var key, revAttr, oldRev, newRev, match, preGUIVal, newNP, newVal;
65235
+ var key, revAttr, oldRev, newRev, match, preGUIVal, newNP, newVal, head, tail;
64919
65236
  var bothInheritAutorange = [];
65237
+ var newAutorangeIn = {};
64920
65238
  var newRangeAccepted = {};
64921
65239
  for(key in layoutPreGUI) {
64922
65240
  match = findUIPattern(key, layoutUIControlPatterns);
64923
65241
  if(match) {
64924
- revAttr = match.attr || (match.head + '.uirevision');
65242
+ head = match.head;
65243
+ tail = match.tail;
65244
+ revAttr = match.attr || (head + '.uirevision');
64925
65245
  oldRev = nestedProperty(oldFullLayout, revAttr).get();
64926
65246
  newRev = oldRev && getNewRev(revAttr, layout);
65247
+
64927
65248
  if(newRev && (newRev === oldRev)) {
64928
65249
  preGUIVal = layoutPreGUI[key];
64929
65250
  if(preGUIVal === null) preGUIVal = undefined;
64930
65251
  newNP = nestedProperty(layout, key);
64931
65252
  newVal = newNP.get();
65253
+
64932
65254
  if(valsMatch(newVal, preGUIVal)) {
64933
- if(newVal === undefined && key.substr(key.length - 9) === 'autorange') {
64934
- bothInheritAutorange.push(key.substr(0, key.length - 10));
65255
+ if(newVal === undefined && tail === 'autorange') {
65256
+ bothInheritAutorange.push(head);
64935
65257
  }
64936
65258
  newNP.set(undefinedToNull(nestedProperty(oldFullLayout, key).get()));
64937
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
+ }
64938
65283
  }
64939
65284
  }
64940
65285
  } else {
@@ -64945,12 +65290,12 @@ function applyUIRevisions(data, layout, oldFullData, oldFullLayout) {
64945
65290
  // so remove it from _preGUI for next time.
64946
65291
  delete layoutPreGUI[key];
64947
65292
 
64948
- if(key.substr(key.length - 8, 6) === 'range[') {
64949
- newRangeAccepted[key.substr(0, key.length - 9)] = 1;
65293
+ if(match && match.tail.substr(0, 6) === 'range[') {
65294
+ newRangeAccepted[match.head] = 1;
64950
65295
  }
64951
65296
  }
64952
65297
 
64953
- // Special logic for `autorange`, since it interacts with `range`:
65298
+ // More special logic for `autorange`, since it interacts with `range`:
64954
65299
  // If the new figure's matching `range` was kept, and `autorange`
64955
65300
  // wasn't supplied explicitly in either the original or the new figure,
64956
65301
  // we shouldn't alter that - but we may just have done that, so fix it.
@@ -82025,6 +82370,9 @@ module.exports = function(opts) {
82025
82370
  // TODO - that's uber hacky... better solution?
82026
82371
  };
82027
82372
 
82373
+ if(opts.autoSize) attrs.size.dflt = 'auto';
82374
+ if(opts.autoColor) attrs.color.dflt = 'auto';
82375
+
82028
82376
  if(opts.arrayOk) {
82029
82377
  attrs.family.arrayOk = true;
82030
82378
  attrs.size.arrayOk = true;
@@ -83758,6 +84106,7 @@ module.exports = {
83758
84106
  valType: 'boolean',
83759
84107
  editType: 'legend',
83760
84108
  },
84109
+
83761
84110
  colorway: {
83762
84111
  valType: 'colorlist',
83763
84112
  dflt: colorAttrs.defaults,
@@ -85170,13 +85519,7 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac
85170
85519
  );
85171
85520
 
85172
85521
  coerce('legendgroup');
85173
- var titleText = coerce('legendgrouptitle.text');
85174
- if(titleText) {
85175
- Lib.coerceFont(coerce, 'legendgrouptitle.font', Lib.extendFlat({}, layout.font, {
85176
- size: Math.round(layout.font.size * 1.1) // default to larger font size
85177
- }));
85178
- }
85179
-
85522
+ coerce('legendgrouptitle.text');
85180
85523
  coerce('legendrank');
85181
85524
 
85182
85525
  traceOut._dfltShowLegend = true;
@@ -85324,16 +85667,14 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut, formatObj) {
85324
85667
 
85325
85668
  coerce('autotypenumbers');
85326
85669
 
85327
- var globalFont = Lib.coerceFont(coerce, 'font');
85328
-
85329
- coerce('title.text', layoutOut._dfltTitle.plot);
85670
+ var font = Lib.coerceFont(coerce, 'font');
85671
+ var fontSize = font.size;
85330
85672
 
85331
- Lib.coerceFont(coerce, 'title.font', {
85332
- family: globalFont.family,
85333
- size: Math.round(globalFont.size * 1.4),
85334
- color: globalFont.color
85335
- });
85673
+ Lib.coerceFont(coerce, 'title.font', Lib.extendFlat({}, font, {
85674
+ size: Math.round(fontSize * 1.4)
85675
+ }));
85336
85676
 
85677
+ coerce('title.text', layoutOut._dfltTitle.plot);
85337
85678
  coerce('title.xref');
85338
85679
  coerce('title.yref');
85339
85680
  coerce('title.x');
@@ -88592,8 +88933,10 @@ module.exports = function arraysToCalcdata(cd, trace) {
88592
88933
 
88593
88934
  var scatterAttrs = _dereq_('../scatter/attributes');
88594
88935
  var baseAttrs = _dereq_('../../plots/attributes');
88936
+ var fontAttrs = _dereq_('../../plots/font_attributes');
88595
88937
  var axisHoverFormat = _dereq_('../../plots/cartesian/axis_format_attributes').axisHoverFormat;
88596
88938
  var hovertemplateAttrs = _dereq_('../../plots/template_attributes').hovertemplateAttrs;
88939
+ var texttemplateAttrs = _dereq_('../../plots/template_attributes').texttemplateAttrs;
88597
88940
  var colorScaleAttrs = _dereq_('../../components/colorscale/attributes');
88598
88941
 
88599
88942
  var extendFlat = _dereq_('../../lib/extend').extendFlat;
@@ -88672,6 +89015,19 @@ module.exports = extendFlat({
88672
89015
  zhoverformat: axisHoverFormat('z', 1),
88673
89016
 
88674
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
+
88675
89031
  showlegend: extendFlat({}, baseAttrs.showlegend, {dflt: false})
88676
89032
  }, {
88677
89033
  transforms: undefined
@@ -88679,7 +89035,7 @@ module.exports = extendFlat({
88679
89035
  colorScaleAttrs('', {cLetter: 'z', autoColorDflt: false})
88680
89036
  );
88681
89037
 
88682
- },{"../../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){
88683
89039
  'use strict';
88684
89040
 
88685
89041
  var Registry = _dereq_('../../registry');
@@ -100553,7 +100909,7 @@ function getSortFunc(opts, d2c) {
100553
100909
  'use strict';
100554
100910
 
100555
100911
  // package version injected by `npm run preprocess`
100556
- exports.version = '2.6.2';
100912
+ exports.version = '2.8.0';
100557
100913
 
100558
100914
  },{}],588:[function(_dereq_,module,exports){
100559
100915
  (function (global){(function (){