plotly.js 2.7.0 → 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 (52) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +3 -3
  3. package/dist/README.md +26 -26
  4. package/dist/plot-schema.json +898 -407
  5. package/dist/plotly-basic.js +489 -185
  6. package/dist/plotly-basic.min.js +4 -4
  7. package/dist/plotly-cartesian.js +894 -326
  8. package/dist/plotly-cartesian.min.js +3 -3
  9. package/dist/plotly-finance.js +489 -185
  10. package/dist/plotly-finance.min.js +4 -4
  11. package/dist/plotly-geo-assets.js +2 -2
  12. package/dist/plotly-geo.js +486 -184
  13. package/dist/plotly-geo.min.js +4 -4
  14. package/dist/plotly-gl2d.js +502 -185
  15. package/dist/plotly-gl2d.min.js +2 -2
  16. package/dist/plotly-gl3d.js +486 -184
  17. package/dist/plotly-gl3d.min.js +2 -2
  18. package/dist/plotly-mapbox.js +486 -184
  19. package/dist/plotly-mapbox.min.js +2 -2
  20. package/dist/plotly-strict.js +1112 -544
  21. package/dist/plotly-strict.min.js +3 -3
  22. package/dist/plotly-with-meta.js +1201 -606
  23. package/dist/plotly.js +1166 -598
  24. package/dist/plotly.min.js +10 -10
  25. package/package.json +4 -4
  26. package/src/components/colorbar/attributes.js +29 -20
  27. package/src/components/colorbar/defaults.js +30 -8
  28. package/src/components/colorbar/draw.js +374 -128
  29. package/src/components/fx/hover.js +5 -2
  30. package/src/components/fx/hoverlabel_defaults.js +4 -2
  31. package/src/components/fx/layout_attributes.js +14 -4
  32. package/src/components/fx/layout_defaults.js +2 -0
  33. package/src/components/legend/attributes.js +7 -0
  34. package/src/components/legend/defaults.js +24 -7
  35. package/src/components/titles/index.js +8 -2
  36. package/src/plot_api/plot_api.js +1 -1
  37. package/src/plots/font_attributes.js +3 -0
  38. package/src/plots/layout_attributes.js +1 -0
  39. package/src/plots/plots.js +7 -15
  40. package/src/traces/contour/attributes.js +12 -0
  41. package/src/traces/contour/defaults.js +9 -1
  42. package/src/traces/heatmap/attributes.js +16 -0
  43. package/src/traces/heatmap/defaults.js +2 -0
  44. package/src/traces/heatmap/label_defaults.js +13 -0
  45. package/src/traces/heatmap/plot.js +203 -4
  46. package/src/traces/histogram2d/attributes.js +8 -0
  47. package/src/traces/histogram2d/defaults.js +4 -0
  48. package/src/traces/histogram2dcontour/attributes.js +3 -1
  49. package/src/traces/histogram2dcontour/defaults.js +8 -1
  50. package/src/traces/pie/calc.js +3 -1
  51. package/src/version.js +1 -1
  52. package/tasks/test_mock.js +1 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * plotly.js (mapbox) v2.7.0
2
+ * plotly.js (mapbox) v2.8.0
3
3
  * Copyright 2012-2021, Plotly, Inc.
4
4
  * All rights reserved.
5
5
  * Licensed under the MIT license
@@ -68827,13 +68827,11 @@ var overrideAll = _dereq_('../../plot_api/edit_types').overrideAll;
68827
68827
 
68828
68828
 
68829
68829
  module.exports = overrideAll({
68830
- // TODO: only right is supported currently
68831
- // orient: {
68832
- // valType: 'enumerated',
68833
- // values: ['left', 'right', 'top', 'bottom'],
68834
- // dflt: 'right',
68835
- //
68836
- // },
68830
+ orientation: {
68831
+ valType: 'enumerated',
68832
+ values: ['h', 'v'],
68833
+ dflt: 'v',
68834
+ },
68837
68835
  thicknessmode: {
68838
68836
  valType: 'enumerated',
68839
68837
  values: ['fraction', 'pixels'],
@@ -68856,14 +68854,12 @@ module.exports = overrideAll({
68856
68854
  },
68857
68855
  x: {
68858
68856
  valType: 'number',
68859
- dflt: 1.02,
68860
68857
  min: -2,
68861
68858
  max: 3,
68862
68859
  },
68863
68860
  xanchor: {
68864
68861
  valType: 'enumerated',
68865
68862
  values: ['left', 'center', 'right'],
68866
- dflt: 'left',
68867
68863
  },
68868
68864
  xpad: {
68869
68865
  valType: 'number',
@@ -68872,14 +68868,12 @@ module.exports = overrideAll({
68872
68868
  },
68873
68869
  y: {
68874
68870
  valType: 'number',
68875
- dflt: 0.5,
68876
68871
  min: -2,
68877
68872
  max: 3,
68878
68873
  },
68879
68874
  yanchor: {
68880
68875
  valType: 'enumerated',
68881
68876
  values: ['top', 'middle', 'bottom'],
68882
- dflt: 'middle',
68883
68877
  },
68884
68878
  ypad: {
68885
68879
  valType: 'number',
@@ -68911,15 +68905,21 @@ module.exports = overrideAll({
68911
68905
  ticks: extendFlat({}, axesAttrs.ticks, {dflt: ''}),
68912
68906
  ticklabeloverflow: extendFlat({}, axesAttrs.ticklabeloverflow, {
68913
68907
  }),
68908
+
68909
+ // ticklabelposition: not used directly, as values depend on orientation
68910
+ // left/right options are for x axes, and top/bottom options are for y axes
68914
68911
  ticklabelposition: {
68915
68912
  valType: 'enumerated',
68916
68913
  values: [
68917
68914
  'outside', 'inside',
68918
68915
  'outside top', 'inside top',
68916
+ 'outside left', 'inside left',
68917
+ 'outside right', 'inside right',
68919
68918
  'outside bottom', 'inside bottom'
68920
68919
  ],
68921
68920
  dflt: 'outside',
68922
68921
  },
68922
+
68923
68923
  ticklen: axesAttrs.ticklen,
68924
68924
  tickwidth: axesAttrs.tickwidth,
68925
68925
  tickcolor: axesAttrs.tickcolor,
@@ -68946,7 +68946,6 @@ module.exports = overrideAll({
68946
68946
  side: {
68947
68947
  valType: 'enumerated',
68948
68948
  values: ['right', 'top', 'bottom'],
68949
- dflt: 'top',
68950
68949
  }
68951
68950
  },
68952
68951
 
@@ -69005,23 +69004,30 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
69005
69004
  return Lib.coerce(colorbarIn, colorbarOut, attributes, attr, dflt);
69006
69005
  }
69007
69006
 
69007
+ var margin = layout.margin || {t: 0, b: 0, l: 0, r: 0};
69008
+ var w = layout.width - margin.l - margin.r;
69009
+ var h = layout.height - margin.t - margin.b;
69010
+
69011
+ var orientation = coerce('orientation');
69012
+ var isVertical = orientation === 'v';
69013
+
69008
69014
  var thicknessmode = coerce('thicknessmode');
69009
69015
  coerce('thickness', (thicknessmode === 'fraction') ?
69010
- 30 / (layout.width - layout.margin.l - layout.margin.r) :
69016
+ 30 / (isVertical ? w : h) :
69011
69017
  30
69012
69018
  );
69013
69019
 
69014
69020
  var lenmode = coerce('lenmode');
69015
69021
  coerce('len', (lenmode === 'fraction') ?
69016
69022
  1 :
69017
- layout.height - layout.margin.t - layout.margin.b
69023
+ isVertical ? h : w
69018
69024
  );
69019
69025
 
69020
- coerce('x');
69021
- coerce('xanchor');
69026
+ coerce('x', isVertical ? 1.02 : 0.5);
69027
+ coerce('xanchor', isVertical ? 'left' : 'center');
69022
69028
  coerce('xpad');
69023
- coerce('y');
69024
- coerce('yanchor');
69029
+ coerce('y', isVertical ? 0.5 : 1.02);
69030
+ coerce('yanchor', isVertical ? 'middle' : 'bottom');
69025
69031
  coerce('ypad');
69026
69032
  Lib.noneOrAll(colorbarIn, colorbarOut, ['x', 'y']);
69027
69033
 
@@ -69031,7 +69037,22 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
69031
69037
  coerce('borderwidth');
69032
69038
  coerce('bgcolor');
69033
69039
 
69034
- var ticklabelposition = coerce('ticklabelposition');
69040
+ var ticklabelposition = Lib.coerce(colorbarIn, colorbarOut, {
69041
+ ticklabelposition: {
69042
+ valType: 'enumerated',
69043
+ dflt: 'outside',
69044
+ values: isVertical ? [
69045
+ 'outside', 'inside',
69046
+ 'outside top', 'inside top',
69047
+ 'outside bottom', 'inside bottom'
69048
+ ] : [
69049
+ 'outside', 'inside',
69050
+ 'outside left', 'inside left',
69051
+ 'outside right', 'inside right'
69052
+ ]
69053
+ }
69054
+ }, 'ticklabelposition');
69055
+
69035
69056
  coerce('ticklabeloverflow', ticklabelposition.indexOf('inside') !== -1 ? 'hide past domain' : 'hide past div');
69036
69057
 
69037
69058
  handleTickValueDefaults(colorbarIn, colorbarOut, coerce, 'linear');
@@ -69053,7 +69074,7 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
69053
69074
  size: Lib.bigFont(tickFont.size)
69054
69075
  });
69055
69076
  Lib.coerceFont(coerce, 'title.font', dfltTitleFont);
69056
- coerce('title.side');
69077
+ coerce('title.side', isVertical ? 'top' : 'right');
69057
69078
  };
69058
69079
 
69059
69080
  },{"../../lib":246,"../../plot_api/plot_template":282,"../../plots/cartesian/prefix_suffix_defaults":312,"../../plots/cartesian/tick_label_defaults":317,"../../plots/cartesian/tick_mark_defaults":318,"../../plots/cartesian/tick_value_defaults":319,"./attributes":115}],118:[function(_dereq_,module,exports){
@@ -69226,18 +69247,20 @@ function makeColorBarData(gd) {
69226
69247
  }
69227
69248
 
69228
69249
  function drawColorBar(g, opts, gd) {
69250
+ var isVertical = opts.orientation === 'v';
69229
69251
  var len = opts.len;
69230
69252
  var lenmode = opts.lenmode;
69231
69253
  var thickness = opts.thickness;
69232
69254
  var thicknessmode = opts.thicknessmode;
69233
69255
  var outlinewidth = opts.outlinewidth;
69234
69256
  var borderwidth = opts.borderwidth;
69257
+ var bgcolor = opts.bgcolor;
69235
69258
  var xanchor = opts.xanchor;
69236
69259
  var yanchor = opts.yanchor;
69237
69260
  var xpad = opts.xpad;
69238
69261
  var ypad = opts.ypad;
69239
69262
  var optsX = opts.x;
69240
- var optsY = opts.y;
69263
+ var optsY = isVertical ? opts.y : 1 - opts.y;
69241
69264
 
69242
69265
  var fullLayout = gd._fullLayout;
69243
69266
  var gs = fullLayout._size;
@@ -69268,23 +69291,35 @@ function drawColorBar(g, opts, gd) {
69268
69291
  // when the colorbar itself is pushing the margins.
69269
69292
  // but then the fractional size is calculated based on the
69270
69293
  // actual graph size, so that the axes will size correctly.
69271
- var thickPx = Math.round(thickness * (thicknessmode === 'fraction' ? gs.w : 1));
69272
- var thickFrac = thickPx / gs.w;
69273
- var lenPx = Math.round(len * (lenmode === 'fraction' ? gs.h : 1));
69274
- var lenFrac = lenPx / gs.h;
69275
- var xpadFrac = xpad / gs.w;
69276
- var yExtraPx = (borderwidth + outlinewidth) / 2;
69277
- var ypadFrac = ypad / gs.h;
69294
+ var thickPx = Math.round(thickness * (thicknessmode === 'fraction' ? (isVertical ? gs.w : gs.h) : 1));
69295
+ var thickFrac = thickPx / (isVertical ? gs.w : gs.h);
69296
+ var lenPx = Math.round(len * (lenmode === 'fraction' ? (isVertical ? gs.h : gs.w) : 1));
69297
+ var lenFrac = lenPx / (isVertical ? gs.h : gs.w);
69278
69298
 
69279
69299
  // x positioning: do it initially just for left anchor,
69280
69300
  // then fix at the end (since we don't know the width yet)
69281
- var uPx = Math.round(optsX * gs.w + xpad);
69282
- // for dragging... this is getting a little muddled...
69283
- var uFrac = optsX - thickFrac * ({center: 0.5, right: 1}[xanchor] || 0);
69301
+ var uPx = Math.round(isVertical ?
69302
+ optsX * gs.w + xpad :
69303
+ optsY * gs.h + ypad
69304
+ );
69284
69305
 
69285
- // y positioning we can do correctly from the start
69286
- var vFrac = optsY + lenFrac * (({top: -0.5, bottom: 0.5}[yanchor] || 0) - 0.5);
69287
- var vPx = Math.round(gs.h * (1 - vFrac));
69306
+ var xRatio = {center: 0.5, right: 1}[xanchor] || 0;
69307
+ var yRatio = {top: 1, middle: 0.5}[yanchor] || 0;
69308
+
69309
+ // for dragging... this is getting a little muddled...
69310
+ var uFrac = isVertical ?
69311
+ optsX - xRatio * thickFrac :
69312
+ optsY - yRatio * thickFrac;
69313
+
69314
+ // y/x positioning (for v/h) we can do correctly from the start
69315
+ var vFrac = isVertical ?
69316
+ optsY - yRatio * lenFrac :
69317
+ optsX - xRatio * lenFrac;
69318
+
69319
+ var vPx = Math.round(isVertical ?
69320
+ gs.h * (1 - vFrac) :
69321
+ gs.w * vFrac
69322
+ );
69288
69323
 
69289
69324
  // stash a few things for makeEditable
69290
69325
  opts._lenFrac = lenFrac;
@@ -69297,12 +69332,23 @@ function drawColorBar(g, opts, gd) {
69297
69332
 
69298
69333
  // position can't go in through supplyDefaults
69299
69334
  // because that restricts it to [0,1]
69300
- ax.position = optsX + xpadFrac + thickFrac;
69335
+ ax.position = thickFrac + (isVertical ?
69336
+ optsX + xpad / gs.w :
69337
+ optsY + ypad / gs.h
69338
+ );
69301
69339
 
69302
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
69340
+ var topOrBottom = ['top', 'bottom'].indexOf(titleSide) !== -1;
69341
+
69342
+ if(isVertical && topOrBottom) {
69303
69343
  ax.title.side = titleSide;
69304
- ax.titlex = optsX + xpadFrac;
69305
- ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
69344
+ ax.titlex = optsX + xpad / gs.w;
69345
+ ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypad / gs.h : ypad / gs.h);
69346
+ }
69347
+
69348
+ if(!isVertical && !topOrBottom) {
69349
+ ax.title.side = titleSide;
69350
+ ax.titley = optsY + ypad / gs.h;
69351
+ ax.titlex = vFrac + xpad / gs.w; // right side
69306
69352
  }
69307
69353
 
69308
69354
  if(line.color && opts.tickmode === 'auto') {
@@ -69327,9 +69373,12 @@ function drawColorBar(g, opts, gd) {
69327
69373
 
69328
69374
  // set domain after init, because we may want to
69329
69375
  // allow it outside [0,1]
69330
- ax.domain = [
69331
- vFrac + ypadFrac,
69332
- vFrac + lenFrac - ypadFrac
69376
+ ax.domain = isVertical ? [
69377
+ vFrac + ypad / gs.h,
69378
+ vFrac + lenFrac - ypad / gs.h
69379
+ ] : [
69380
+ vFrac + xpad / gs.w,
69381
+ vFrac + lenFrac - xpad / gs.w
69333
69382
  ];
69334
69383
 
69335
69384
  ax.setScale();
@@ -69339,9 +69388,13 @@ function drawColorBar(g, opts, gd) {
69339
69388
  var titleCont = g.select('.' + cn.cbtitleunshift)
69340
69389
  .attr('transform', strTranslate(-Math.round(gs.l), -Math.round(gs.t)));
69341
69390
 
69391
+ var ticklabelposition = ax.ticklabelposition;
69392
+ var titleFontSize = ax.title.font.size;
69393
+
69342
69394
  var axLayer = g.select('.' + cn.cbaxis);
69343
69395
  var titleEl;
69344
69396
  var titleHeight = 0;
69397
+ var titleWidth = 0;
69345
69398
 
69346
69399
  function drawTitle(titleClass, titleOpts) {
69347
69400
  var dfltTitleOpts = {
@@ -69366,54 +69419,98 @@ function drawColorBar(g, opts, gd) {
69366
69419
  }
69367
69420
 
69368
69421
  function drawDummyTitle() {
69369
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
69370
- // draw the title so we know how much room it needs
69371
- // when we squish the axis. This one only applies to
69372
- // top or bottom titles, not right side.
69373
- var x = gs.l + (optsX + xpadFrac) * gs.w;
69374
- var fontSize = ax.title.font.size;
69375
- var y;
69422
+ // draw the title so we know how much room it needs
69423
+ // when we squish the axis.
69424
+ // On vertical colorbars this only applies to top or bottom titles, not right side.
69425
+ // On horizontal colorbars this only applies to right, etc.
69426
+
69427
+ if(
69428
+ (isVertical && topOrBottom) ||
69429
+ (!isVertical && !topOrBottom)
69430
+ ) {
69431
+ var x, y;
69376
69432
 
69377
69433
  if(titleSide === 'top') {
69378
- y = (1 - (vFrac + lenFrac - ypadFrac)) * gs.h +
69379
- gs.t + 3 + fontSize * 0.75;
69380
- } else {
69381
- y = (1 - (vFrac + ypadFrac)) * gs.h +
69382
- gs.t - 3 - fontSize * 0.25;
69434
+ x = xpad + gs.l + gs.w * optsX;
69435
+ y = ypad + gs.t + gs.h * (1 - vFrac - lenFrac) + 3 + titleFontSize * 0.75;
69436
+ }
69437
+
69438
+ if(titleSide === 'bottom') {
69439
+ x = xpad + gs.l + gs.w * optsX;
69440
+ y = ypad + gs.t + gs.h * (1 - vFrac) - 3 - titleFontSize * 0.25;
69383
69441
  }
69442
+
69443
+ if(titleSide === 'right') {
69444
+ y = ypad + gs.t + gs.h * optsY + 3 + titleFontSize * 0.75;
69445
+ x = xpad + gs.l + gs.w * vFrac;
69446
+ }
69447
+
69384
69448
  drawTitle(ax._id + 'title', {
69385
- attributes: {x: x, y: y, 'text-anchor': 'start'}
69449
+ attributes: {x: x, y: y, 'text-anchor': isVertical ? 'start' : 'middle'}
69386
69450
  });
69387
69451
  }
69388
69452
  }
69389
69453
 
69390
69454
  function drawCbTitle() {
69391
- if(['top', 'bottom'].indexOf(titleSide) === -1) {
69392
- var fontSize = ax.title.font.size;
69393
- var y = ax._offset + ax._length / 2;
69394
- var x = gs.l + (ax.position || 0) * gs.w + ((ax.side === 'right') ?
69395
- 10 + fontSize * ((ax.showticklabels ? 1 : 0.5)) :
69396
- -10 - fontSize * ((ax.showticklabels ? 0.5 : 0)));
69397
-
69398
- // the 'h' + is a hack to get around the fact that
69399
- // convertToTspans rotates any 'y...' class by 90 degrees.
69400
- // TODO: find a better way to control this.
69401
- drawTitle('h' + ax._id + 'title', {
69455
+ if(
69456
+ (isVertical && !topOrBottom) ||
69457
+ (!isVertical && topOrBottom)
69458
+ ) {
69459
+ var pos = ax.position || 0;
69460
+ var mid = ax._offset + ax._length / 2;
69461
+ var x, y;
69462
+
69463
+ if(titleSide === 'right') {
69464
+ y = mid;
69465
+ x = gs.l + gs.w * pos + 10 + titleFontSize * (
69466
+ ax.showticklabels ? 1 : 0.5
69467
+ );
69468
+ } else {
69469
+ x = mid;
69470
+
69471
+ if(titleSide === 'bottom') {
69472
+ y = gs.t + gs.h * pos + 10 + (
69473
+ ticklabelposition.indexOf('inside') === -1 ?
69474
+ ax.tickfont.size :
69475
+ 0
69476
+ ) + (
69477
+ ax.ticks !== 'intside' ?
69478
+ opts.ticklen || 0 :
69479
+ 0
69480
+ );
69481
+ }
69482
+
69483
+ if(titleSide === 'top') {
69484
+ var nlines = title.text.split('<br>').length;
69485
+ y = gs.t + gs.h * pos + 10 - thickPx - LINE_SPACING * titleFontSize * nlines;
69486
+ }
69487
+ }
69488
+
69489
+ drawTitle((isVertical ?
69490
+ // the 'h' + is a hack to get around the fact that
69491
+ // convertToTspans rotates any 'y...' class by 90 degrees.
69492
+ // TODO: find a better way to control this.
69493
+ 'h' :
69494
+ 'v'
69495
+ ) + ax._id + 'title', {
69402
69496
  avoid: {
69403
69497
  selection: d3.select(gd).selectAll('g.' + ax._id + 'tick'),
69404
69498
  side: titleSide,
69405
- offsetLeft: gs.l,
69406
- offsetTop: 0,
69407
- maxShift: fullLayout.width
69499
+ offsetTop: isVertical ? 0 : gs.t,
69500
+ offsetLeft: isVertical ? gs.l : 0,
69501
+ maxShift: isVertical ? fullLayout.width : fullLayout.height
69408
69502
  },
69409
69503
  attributes: {x: x, y: y, 'text-anchor': 'middle'},
69410
- transform: {rotate: '-90', offset: 0}
69504
+ transform: {rotate: isVertical ? -90 : 0, offset: 0}
69411
69505
  });
69412
69506
  }
69413
69507
  }
69414
69508
 
69415
69509
  function drawAxis() {
69416
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
69510
+ if(
69511
+ (!isVertical && !topOrBottom) ||
69512
+ (isVertical && topOrBottom)
69513
+ ) {
69417
69514
  // squish the axis top to make room for the title
69418
69515
  var titleGroup = g.select('.' + cn.cbtitle);
69419
69516
  var titleText = titleGroup.select('text');
@@ -69425,39 +69522,63 @@ function drawColorBar(g, opts, gd) {
69425
69522
  if(titleText.node()) {
69426
69523
  lineSize = parseInt(titleText.node().style.fontSize, 10) * LINE_SPACING;
69427
69524
  }
69525
+
69526
+ var bb;
69428
69527
  if(mathJaxNode) {
69429
- titleHeight = Drawing.bBox(mathJaxNode).height;
69528
+ bb = Drawing.bBox(mathJaxNode);
69529
+ titleWidth = bb.width;
69530
+ titleHeight = bb.height;
69430
69531
  if(titleHeight > lineSize) {
69431
69532
  // not entirely sure how mathjax is doing
69432
69533
  // vertical alignment, but this seems to work.
69433
69534
  titleTrans[1] -= (titleHeight - lineSize) / 2;
69434
69535
  }
69435
69536
  } else if(titleText.node() && !titleText.classed(cn.jsPlaceholder)) {
69436
- titleHeight = Drawing.bBox(titleText.node()).height;
69537
+ bb = Drawing.bBox(titleText.node());
69538
+ titleWidth = bb.width;
69539
+ titleHeight = bb.height;
69437
69540
  }
69438
- if(titleHeight) {
69439
- // buffer btwn colorbar and title
69440
- // TODO: configurable
69441
- titleHeight += 5;
69442
69541
 
69443
- if(titleSide === 'top') {
69444
- ax.domain[1] -= titleHeight / gs.h;
69445
- titleTrans[1] *= -1;
69446
- } else {
69447
- ax.domain[0] += titleHeight / gs.h;
69448
- var nlines = svgTextUtils.lineCount(titleText);
69449
- titleTrans[1] += (1 - nlines) * lineSize;
69542
+ if(isVertical) {
69543
+ if(titleHeight) {
69544
+ // buffer btwn colorbar and title
69545
+ // TODO: configurable
69546
+ titleHeight += 5;
69547
+
69548
+ if(titleSide === 'top') {
69549
+ ax.domain[1] -= titleHeight / gs.h;
69550
+ titleTrans[1] *= -1;
69551
+ } else {
69552
+ ax.domain[0] += titleHeight / gs.h;
69553
+ var nlines = svgTextUtils.lineCount(titleText);
69554
+ titleTrans[1] += (1 - nlines) * lineSize;
69555
+ }
69556
+
69557
+ titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
69558
+ ax.setScale();
69450
69559
  }
69560
+ } else { // horizontal colorbars
69561
+ if(titleWidth) {
69562
+ if(titleSide === 'right') {
69563
+ ax.domain[0] += (titleWidth + titleFontSize / 2) / gs.w;
69564
+ }
69451
69565
 
69452
- titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
69453
- ax.setScale();
69566
+ titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
69567
+ ax.setScale();
69568
+ }
69454
69569
  }
69455
69570
  }
69456
69571
 
69457
69572
  g.selectAll('.' + cn.cbfills + ',.' + cn.cblines)
69458
- .attr('transform', strTranslate(0, Math.round(gs.h * (1 - ax.domain[1]))));
69573
+ .attr('transform', isVertical ?
69574
+ strTranslate(0, Math.round(gs.h * (1 - ax.domain[1]))) :
69575
+ strTranslate(Math.round(gs.w * ax.domain[0]), 0)
69576
+ );
69459
69577
 
69460
- axLayer.attr('transform', strTranslate(0, Math.round(-gs.t)));
69578
+ axLayer.attr('transform', isVertical ?
69579
+ strTranslate(0, Math.round(-gs.t)) :
69580
+ strTranslate(Math.round(-gs.l), 0)
69581
+ );
69461
69582
 
69462
69583
  var fills = g.select('.' + cn.cbfills)
69463
69584
  .selectAll('rect.' + cn.cbfill)
@@ -69483,20 +69604,22 @@ function drawColorBar(g, opts, gd) {
69483
69604
 
69484
69605
  // offset the side adjoining the next rectangle so they
69485
69606
  // overlap, to prevent antialiasing gaps
69486
- z[1] = Lib.constrain(z[1] + (z[1] > z[0]) ? 1 : -1, zBounds[0], zBounds[1]);
69487
-
69607
+ if(isVertical) {
69608
+ z[1] = Lib.constrain(z[1] + (z[1] > z[0]) ? 1 : -1, zBounds[0], zBounds[1]);
69609
+ } /* else {
69610
+ // TODO: horizontal case
69611
+ } */
69488
69612
 
69489
69613
  // Colorbar cannot currently support opacities so we
69490
69614
  // use an opaque fill even when alpha channels present
69491
- var fillEl = d3.select(this).attr({
69492
- x: uPx,
69493
- width: Math.max(thickPx, 2),
69494
- y: d3.min(z),
69495
- height: Math.max(d3.max(z) - d3.min(z), 2),
69496
- });
69615
+ var fillEl = d3.select(this)
69616
+ .attr(isVertical ? 'x' : 'y', uPx)
69617
+ .attr(isVertical ? 'y' : 'x', d3.min(z))
69618
+ .attr(isVertical ? 'width' : 'height', Math.max(thickPx, 2))
69619
+ .attr(isVertical ? 'height' : 'width', Math.max(d3.max(z) - d3.min(z), 2));
69497
69620
 
69498
69621
  if(opts._fillgradient) {
69499
- Drawing.gradient(fillEl, gd, opts._id, 'vertical', opts._fillgradient, 'fill');
69622
+ Drawing.gradient(fillEl, gd, opts._id, isVertical ? 'vertical' : 'horizontalreversed', opts._fillgradient, 'fill');
69500
69623
  } else {
69501
69624
  // tinycolor can't handle exponents and
69502
69625
  // at this scale, removing it makes no difference.
@@ -69512,9 +69635,15 @@ function drawColorBar(g, opts, gd) {
69512
69635
  .classed(cn.cbline, true);
69513
69636
  lines.exit().remove();
69514
69637
  lines.each(function(d) {
69638
+ var a = uPx;
69639
+ var b = (Math.round(ax.c2p(d)) + (line.width / 2) % 1);
69640
+
69515
69641
  d3.select(this)
69516
- .attr('d', 'M' + uPx + ',' +
69517
- (Math.round(ax.c2p(d)) + (line.width / 2) % 1) + 'h' + thickPx)
69642
+ .attr('d', 'M' +
69643
+ (isVertical ? a + ',' + b : b + ',' + a) +
69644
+ (isVertical ? 'h' : 'v') +
69645
+ thickPx
69646
+ )
69518
69647
  .call(Drawing.lineGroupStyle, line.width, lineColormap(d), line.dash);
69519
69648
  });
69520
69649
 
@@ -69547,82 +69676,211 @@ function drawColorBar(g, opts, gd) {
69547
69676
  // TODO: why are we redrawing multiple times now with this?
69548
69677
  // I guess autoMargin doesn't like being post-promise?
69549
69678
  function positionCB() {
69679
+ var bb;
69550
69680
  var innerThickness = thickPx + outlinewidth / 2;
69551
- if(ax.ticklabelposition.indexOf('inside') === -1) {
69552
- innerThickness += Drawing.bBox(axLayer.node()).width;
69681
+ if(ticklabelposition.indexOf('inside') === -1) {
69682
+ bb = Drawing.bBox(axLayer.node());
69683
+ innerThickness += isVertical ? bb.width : bb.height;
69553
69684
  }
69554
69685
 
69555
69686
  titleEl = titleCont.select('text');
69556
69687
 
69688
+ var titleWidth = 0;
69689
+
69690
+ var topSideVertical = isVertical && titleSide === 'top';
69691
+ var rightSideHorizontal = !isVertical && titleSide === 'right';
69692
+
69693
+ var moveY = 0;
69694
+
69557
69695
  if(titleEl.node() && !titleEl.classed(cn.jsPlaceholder)) {
69696
+ var _titleHeight;
69697
+
69558
69698
  var mathJaxNode = titleCont.select('.h' + ax._id + 'title-math-group').node();
69559
- var titleWidth;
69560
- if(mathJaxNode && ['top', 'bottom'].indexOf(titleSide) !== -1) {
69561
- titleWidth = Drawing.bBox(mathJaxNode).width;
69699
+ if(mathJaxNode && (
69700
+ (isVertical && topOrBottom) ||
69701
+ (!isVertical && !topOrBottom)
69702
+ )) {
69703
+ bb = Drawing.bBox(mathJaxNode);
69704
+ titleWidth = bb.width;
69705
+ _titleHeight = bb.height;
69562
69706
  } else {
69563
69707
  // note: the formula below works for all title sides,
69564
69708
  // (except for top/bottom mathjax, above)
69565
69709
  // but the weird gs.l is because the titleunshift
69566
69710
  // transform gets removed by Drawing.bBox
69567
- titleWidth = Drawing.bBox(titleCont.node()).right - uPx - gs.l;
69711
+ bb = Drawing.bBox(titleCont.node());
69712
+ titleWidth = bb.right - gs.l - (isVertical ? uPx : vPx);
69713
+ _titleHeight = bb.bottom - gs.t - (isVertical ? vPx : uPx);
69714
+
69715
+ if(
69716
+ !isVertical && titleSide === 'top'
69717
+ ) {
69718
+ innerThickness += bb.height;
69719
+ moveY = bb.height;
69720
+ }
69721
+ }
69722
+
69723
+ if(rightSideHorizontal) {
69724
+ titleEl.attr('transform', strTranslate(titleWidth / 2 + titleFontSize / 2, 0));
69725
+
69726
+ titleWidth *= 2;
69568
69727
  }
69569
- innerThickness = Math.max(innerThickness, titleWidth);
69728
+
69729
+ innerThickness = Math.max(innerThickness,
69730
+ isVertical ? titleWidth : _titleHeight
69731
+ );
69570
69732
  }
69571
69733
 
69572
- var outerThickness = 2 * xpad + innerThickness + borderwidth + outlinewidth / 2;
69734
+ var outerThickness = (isVertical ?
69735
+ xpad :
69736
+ ypad
69737
+ ) * 2 + innerThickness + borderwidth + outlinewidth / 2;
69573
69738
 
69574
- g.select('.' + cn.cbbg).attr({
69575
- x: uPx - xpad - (borderwidth + outlinewidth) / 2,
69576
- y: vPx - lenPx - yExtraPx,
69577
- width: Math.max(outerThickness, 2),
69578
- height: Math.max(lenPx + 2 * yExtraPx, 2)
69579
- })
69580
- .call(Color.fill, opts.bgcolor)
69739
+ var hColorbarMoveTitle = 0;
69740
+ if(!isVertical && title.text && yanchor === 'bottom' && optsY <= 0) {
69741
+ hColorbarMoveTitle = outerThickness / 2;
69742
+
69743
+ outerThickness += hColorbarMoveTitle;
69744
+ moveY += hColorbarMoveTitle;
69745
+ }
69746
+ fullLayout._hColorbarMoveTitle = hColorbarMoveTitle;
69747
+ fullLayout._hColorbarMoveCBTitle = moveY;
69748
+
69749
+ var extraW = borderwidth + outlinewidth;
69750
+
69751
+ g.select('.' + cn.cbbg)
69752
+ .attr('x', (isVertical ? uPx : vPx) - extraW / 2 - (isVertical ? xpad : 0))
69753
+ .attr('y', (isVertical ? vPx : uPx) - (isVertical ? lenPx : ypad + moveY - hColorbarMoveTitle))
69754
+ .attr(isVertical ? 'width' : 'height', Math.max(outerThickness - hColorbarMoveTitle, 2))
69755
+ .attr(isVertical ? 'height' : 'width', Math.max(lenPx + extraW, 2))
69756
+ .call(Color.fill, bgcolor)
69581
69757
  .call(Color.stroke, opts.bordercolor)
69582
69758
  .style('stroke-width', borderwidth);
69583
69759
 
69584
- g.selectAll('.' + cn.cboutline).attr({
69585
- x: uPx,
69586
- y: vPx - lenPx + ypad + (titleSide === 'top' ? titleHeight : 0),
69587
- width: Math.max(thickPx, 2),
69588
- height: Math.max(lenPx - 2 * ypad - titleHeight, 2)
69589
- })
69760
+ var moveX = rightSideHorizontal ? Math.max(titleWidth - 10, 0) : 0;
69761
+
69762
+ g.selectAll('.' + cn.cboutline)
69763
+ .attr('x', (isVertical ? uPx : vPx + xpad) + moveX)
69764
+ .attr('y', (isVertical ? vPx + ypad - lenPx : uPx) + (topSideVertical ? titleHeight : 0))
69765
+ .attr(isVertical ? 'width' : 'height', Math.max(thickPx, 2))
69766
+ .attr(isVertical ? 'height' : 'width', Math.max(lenPx - (isVertical ?
69767
+ 2 * ypad + titleHeight :
69768
+ 2 * xpad + moveX
69769
+ ), 2))
69590
69770
  .call(Color.stroke, opts.outlinecolor)
69591
69771
  .style({
69592
69772
  fill: 'none',
69593
69773
  'stroke-width': outlinewidth
69594
69774
  });
69595
69775
 
69596
- // fix positioning for xanchor!='left'
69597
- var xoffset = ({center: 0.5, right: 1}[xanchor] || 0) * outerThickness;
69598
- g.attr('transform', strTranslate(gs.l - xoffset, gs.t));
69776
+ g.attr('transform', strTranslate(
69777
+ gs.l - (isVertical ? xRatio * outerThickness : 0),
69778
+ gs.t - (isVertical ? 0 : (1 - yRatio) * outerThickness - moveY)
69779
+ ));
69780
+
69781
+ if(!isVertical && (
69782
+ borderwidth || (
69783
+ tinycolor(bgcolor).getAlpha() &&
69784
+ !tinycolor.equals(fullLayout.paper_bgcolor, bgcolor)
69785
+ )
69786
+ )) {
69787
+ // for horizontal colorbars when there is a border line or having different background color
69788
+ // hide/adjust x positioning for the first/last tick labels if they go outside the border
69789
+ var tickLabels = axLayer.selectAll('text');
69790
+ var numTicks = tickLabels[0].length;
69791
+
69792
+ var border = g.select('.' + cn.cbbg).node();
69793
+ var oBb = Drawing.bBox(border);
69794
+ var oTr = Drawing.getTranslate(g);
69795
+
69796
+ var TEXTPAD = 2;
69797
+
69798
+ tickLabels.each(function(d, i) {
69799
+ var first = 0;
69800
+ var last = numTicks - 1;
69801
+ if(i === first || i === last) {
69802
+ var iBb = Drawing.bBox(this);
69803
+ var iTr = Drawing.getTranslate(this);
69804
+ var deltaX;
69805
+
69806
+ if(i === last) {
69807
+ var iRight = iBb.right + iTr.x;
69808
+ var oRight = oBb.right + oTr.x + vPx - borderwidth - TEXTPAD + optsX;
69809
+
69810
+ deltaX = oRight - iRight;
69811
+ if(deltaX > 0) deltaX = 0;
69812
+ } else if(i === first) {
69813
+ var iLeft = iBb.left + iTr.x;
69814
+ var oLeft = oBb.left + oTr.x + vPx + borderwidth + TEXTPAD;
69815
+
69816
+ deltaX = oLeft - iLeft;
69817
+ if(deltaX < 0) deltaX = 0;
69818
+ }
69819
+
69820
+ if(deltaX) {
69821
+ if(numTicks < 3) { // adjust position
69822
+ this.setAttribute('transform',
69823
+ 'translate(' + deltaX + ',0) ' +
69824
+ this.getAttribute('transform')
69825
+ );
69826
+ } else { // hide
69827
+ this.setAttribute('visibility', 'hidden');
69828
+ }
69829
+ }
69830
+ }
69831
+ });
69832
+ }
69599
69833
 
69600
69834
  // auto margin adjustment
69601
69835
  var marginOpts = {};
69836
+ var lFrac = FROM_TL[xanchor];
69837
+ var rFrac = FROM_BR[xanchor];
69602
69838
  var tFrac = FROM_TL[yanchor];
69603
69839
  var bFrac = FROM_BR[yanchor];
69604
- if(lenmode === 'pixels') {
69605
- marginOpts.y = optsY;
69606
- marginOpts.t = lenPx * tFrac;
69607
- marginOpts.b = lenPx * bFrac;
69608
- } else {
69609
- marginOpts.t = marginOpts.b = 0;
69610
- marginOpts.yt = optsY + len * tFrac;
69611
- marginOpts.yb = optsY - len * bFrac;
69612
- }
69613
69840
 
69614
- var lFrac = FROM_TL[xanchor];
69615
- var rFrac = FROM_BR[xanchor];
69616
- if(thicknessmode === 'pixels') {
69617
- marginOpts.x = optsX;
69618
- marginOpts.l = outerThickness * lFrac;
69619
- marginOpts.r = outerThickness * rFrac;
69620
- } else {
69621
- var extraThickness = outerThickness - thickPx;
69622
- marginOpts.l = extraThickness * lFrac;
69623
- marginOpts.r = extraThickness * rFrac;
69624
- marginOpts.xl = optsX - thickness * lFrac;
69625
- marginOpts.xr = optsX + thickness * rFrac;
69841
+ var extraThickness = outerThickness - thickPx;
69842
+ if(isVertical) {
69843
+ if(lenmode === 'pixels') {
69844
+ marginOpts.y = optsY;
69845
+ marginOpts.t = lenPx * tFrac;
69846
+ marginOpts.b = lenPx * bFrac;
69847
+ } else {
69848
+ marginOpts.t = marginOpts.b = 0;
69849
+ marginOpts.yt = optsY + len * tFrac;
69850
+ marginOpts.yb = optsY - len * bFrac;
69851
+ }
69852
+
69853
+ if(thicknessmode === 'pixels') {
69854
+ marginOpts.x = optsX;
69855
+ marginOpts.l = outerThickness * lFrac;
69856
+ marginOpts.r = outerThickness * rFrac;
69857
+ } else {
69858
+ marginOpts.l = extraThickness * lFrac;
69859
+ marginOpts.r = extraThickness * rFrac;
69860
+ marginOpts.xl = optsX - thickness * lFrac;
69861
+ marginOpts.xr = optsX + thickness * rFrac;
69862
+ }
69863
+ } else { // horizontal colorbars
69864
+ if(lenmode === 'pixels') {
69865
+ marginOpts.x = optsX;
69866
+ marginOpts.l = lenPx * lFrac;
69867
+ marginOpts.r = lenPx * rFrac;
69868
+ } else {
69869
+ marginOpts.l = marginOpts.r = 0;
69870
+ marginOpts.xl = optsX + len * lFrac;
69871
+ marginOpts.xr = optsX - len * rFrac;
69872
+ }
69873
+
69874
+ if(thicknessmode === 'pixels') {
69875
+ marginOpts.y = 1 - optsY;
69876
+ marginOpts.t = outerThickness * tFrac;
69877
+ marginOpts.b = outerThickness * bFrac;
69878
+ } else {
69879
+ marginOpts.t = extraThickness * tFrac;
69880
+ marginOpts.b = extraThickness * bFrac;
69881
+ marginOpts.yt = optsY - thickness * tFrac;
69882
+ marginOpts.yb = optsY + thickness * bFrac;
69883
+ }
69626
69884
  }
69627
69885
 
69628
69886
  Plots.autoMargin(gd, opts._id, marginOpts);
@@ -69639,6 +69897,7 @@ function drawColorBar(g, opts, gd) {
69639
69897
  }
69640
69898
 
69641
69899
  function makeEditable(g, opts, gd) {
69900
+ var isVertical = opts.orientation === 'v';
69642
69901
  var fullLayout = gd._fullLayout;
69643
69902
  var gs = fullLayout._size;
69644
69903
  var t0, xf, yf;
@@ -69653,9 +69912,13 @@ function makeEditable(g, opts, gd) {
69653
69912
  moveFn: function(dx, dy) {
69654
69913
  g.attr('transform', t0 + strTranslate(dx, dy));
69655
69914
 
69656
- xf = dragElement.align(opts._uFrac + (dx / gs.w), opts._thickFrac,
69915
+ xf = dragElement.align(
69916
+ (isVertical ? opts._uFrac : opts._vFrac) + (dx / gs.w),
69917
+ isVertical ? opts._thickFrac : opts._lenFrac,
69657
69918
  0, 1, opts.xanchor);
69658
- yf = dragElement.align(opts._vFrac - (dy / gs.h), opts._lenFrac,
69919
+ yf = dragElement.align(
69920
+ (isVertical ? opts._vFrac : (1 - opts._uFrac)) - (dy / gs.h),
69921
+ isVertical ? opts._lenFrac : opts._thickFrac,
69659
69922
  0, 1, opts.yanchor);
69660
69923
 
69661
69924
  var csr = dragElement.getCursor(xf, yf, opts.xanchor, opts.yanchor);
@@ -69732,6 +69995,8 @@ function calcLevels(gd, opts, zrange) {
69732
69995
  function mockColorBarAxis(gd, opts, zrange) {
69733
69996
  var fullLayout = gd._fullLayout;
69734
69997
 
69998
+ var isVertical = opts.orientation === 'v';
69999
+
69735
70000
  var cbAxisIn = {
69736
70001
  type: 'linear',
69737
70002
  range: zrange,
@@ -69762,17 +70027,19 @@ function mockColorBarAxis(gd, opts, zrange) {
69762
70027
  title: opts.title,
69763
70028
  showline: true,
69764
70029
  anchor: 'free',
69765
- side: 'right',
70030
+ side: isVertical ? 'right' : 'bottom',
69766
70031
  position: 1
69767
70032
  };
69768
70033
 
70034
+ var letter = isVertical ? 'y' : 'x';
70035
+
69769
70036
  var cbAxisOut = {
69770
70037
  type: 'linear',
69771
- _id: 'y' + opts._id
70038
+ _id: letter + opts._id
69772
70039
  };
69773
70040
 
69774
70041
  var axisOptions = {
69775
- letter: 'y',
70042
+ letter: letter,
69776
70043
  font: fullLayout.font,
69777
70044
  noHover: true,
69778
70045
  noTickson: true,
@@ -75385,7 +75652,9 @@ function createHoverText(hoverData, opts) {
75385
75652
  orientation: 'v'
75386
75653
  }
75387
75654
  };
75388
- var mockLayoutOut = {};
75655
+ var mockLayoutOut = {
75656
+ font: font
75657
+ };
75389
75658
  legendSupplyDefaults(mockLayoutIn, mockLayoutOut, gd._fullData);
75390
75659
  var mockLegend = mockLayoutOut.legend;
75391
75660
 
@@ -75426,7 +75695,8 @@ function createHoverText(hoverData, opts) {
75426
75695
 
75427
75696
  // Draw unified hover label
75428
75697
  mockLegend._inHover = true;
75429
- mockLegend._groupTitleFont = font;
75698
+ mockLegend._groupTitleFont = hoverlabel.grouptitlefont;
75699
+
75430
75700
  legendDraw(gd, mockLegend);
75431
75701
 
75432
75702
  // Position the hover
@@ -76428,9 +76698,11 @@ var isUnifiedHover = _dereq_('./helpers').isUnifiedHover;
76428
76698
  module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts) {
76429
76699
  opts = opts || {};
76430
76700
 
76701
+ var hasLegend = contOut.legend;
76702
+
76431
76703
  function inheritFontAttr(attr) {
76432
76704
  if(!opts.font[attr]) {
76433
- opts.font[attr] = contOut.legend ? contOut.legend.font[attr] : contOut.font[attr];
76705
+ opts.font[attr] = hasLegend ? contOut.legend.font[attr] : contOut.font[attr];
76434
76706
  }
76435
76707
  }
76436
76708
 
@@ -76441,7 +76713,7 @@ module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts
76441
76713
  inheritFontAttr('family');
76442
76714
  inheritFontAttr('color');
76443
76715
 
76444
- if(contOut.legend) {
76716
+ if(hasLegend) {
76445
76717
  if(!opts.bgcolor) opts.bgcolor = Color.combine(contOut.legend.bgcolor, contOut.paper_bgcolor);
76446
76718
  if(!opts.bordercolor) opts.bordercolor = contOut.legend.bordercolor;
76447
76719
  } else {
@@ -76550,11 +76822,13 @@ function castHoverinfo(trace, fullLayout, ptNumber) {
76550
76822
 
76551
76823
  var constants = _dereq_('./constants');
76552
76824
 
76553
- var fontAttrs = _dereq_('../../plots/font_attributes')({
76825
+ var fontAttrs = _dereq_('../../plots/font_attributes');
76826
+
76827
+ var font = fontAttrs({
76554
76828
  editType: 'none',
76555
76829
  });
76556
- fontAttrs.family.dflt = constants.HOVERFONT;
76557
- fontAttrs.size.dflt = constants.HOVERFONTSIZE;
76830
+ font.family.dflt = constants.HOVERFONT;
76831
+ font.size.dflt = constants.HOVERFONTSIZE;
76558
76832
 
76559
76833
  module.exports = {
76560
76834
  clickmode: {
@@ -76610,7 +76884,10 @@ module.exports = {
76610
76884
  valType: 'color',
76611
76885
  editType: 'none',
76612
76886
  },
76613
- font: fontAttrs,
76887
+ font: font,
76888
+ grouptitlefont: fontAttrs({
76889
+ editType: 'none',
76890
+ }),
76614
76891
  align: {
76615
76892
  valType: 'enumerated',
76616
76893
  values: ['left', 'right', 'auto'],
@@ -76623,6 +76900,7 @@ module.exports = {
76623
76900
  dflt: 15,
76624
76901
  editType: 'none',
76625
76902
  },
76903
+
76626
76904
  editType: 'none'
76627
76905
  },
76628
76906
  selectdirection: {
@@ -76670,6 +76948,8 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut) {
76670
76948
  }
76671
76949
 
76672
76950
  handleHoverLabelDefaults(layoutIn, layoutOut, coerce);
76951
+
76952
+ Lib.coerceFont(coerce, 'hoverlabel.grouptitlefont', layoutOut.hoverlabel.font);
76673
76953
  };
76674
76954
 
76675
76955
  },{"../../lib":246,"./hoverlabel_defaults":152,"./hovermode_defaults":153,"./layout_attributes":155}],157:[function(_dereq_,module,exports){
@@ -77553,6 +77833,9 @@ module.exports = {
77553
77833
  font: fontAttrs({
77554
77834
  editType: 'legend',
77555
77835
  }),
77836
+ grouptitlefont: fontAttrs({
77837
+ editType: 'legend',
77838
+ }),
77556
77839
  orientation: {
77557
77840
  valType: 'enumerated',
77558
77841
  values: ['v', 'h'],
@@ -77676,6 +77959,7 @@ var Registry = _dereq_('../../registry');
77676
77959
  var Lib = _dereq_('../../lib');
77677
77960
  var Template = _dereq_('../../plot_api/plot_template');
77678
77961
 
77962
+ var plotsAttrs = _dereq_('../../plots/attributes');
77679
77963
  var attributes = _dereq_('./attributes');
77680
77964
  var basePlotLayoutAttributes = _dereq_('../../plots/layout_attributes');
77681
77965
  var helpers = _dereq_('./helpers');
@@ -77683,13 +77967,30 @@ var helpers = _dereq_('./helpers');
77683
77967
 
77684
77968
  module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
77685
77969
  var containerIn = layoutIn.legend || {};
77970
+ var containerOut = Template.newContainer(layoutOut, 'legend');
77971
+
77972
+ function coerce(attr, dflt) {
77973
+ return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
77974
+ }
77975
+
77976
+ var trace;
77977
+ var traceCoerce = function(attr, dflt) {
77978
+ var traceIn = trace._input;
77979
+ var traceOut = trace;
77980
+ return Lib.coerce(traceIn, traceOut, plotsAttrs, attr, dflt);
77981
+ };
77982
+
77983
+ var globalFont = layoutOut.font || {};
77984
+ var grouptitlefont = Lib.coerceFont(coerce, 'grouptitlefont', Lib.extendFlat({}, globalFont, {
77985
+ size: Math.round(globalFont.size * 1.1)
77986
+ }));
77686
77987
 
77687
77988
  var legendTraceCount = 0;
77688
77989
  var legendReallyHasATrace = false;
77689
77990
  var defaultOrder = 'normal';
77690
77991
 
77691
77992
  for(var i = 0; i < fullData.length; i++) {
77692
- var trace = fullData[i];
77993
+ trace = fullData[i];
77693
77994
 
77694
77995
  if(!trace.visible) continue;
77695
77996
 
@@ -77716,6 +78017,8 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
77716
78017
  legendTraceCount++;
77717
78018
  }
77718
78019
  }
78020
+
78021
+ Lib.coerceFont(traceCoerce, 'legendgrouptitle.font', grouptitlefont);
77719
78022
  }
77720
78023
 
77721
78024
  if((Registry.traceIs(trace, 'bar') && layoutOut.barmode === 'stack') ||
@@ -77734,13 +78037,10 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
77734
78037
  basePlotLayoutAttributes, 'showlegend',
77735
78038
  legendReallyHasATrace && legendTraceCount > 1);
77736
78039
 
77737
- if(showLegend === false && !containerIn.uirevision) return;
77738
-
77739
- var containerOut = Template.newContainer(layoutOut, 'legend');
78040
+ // delete legend
78041
+ if(showLegend === false) layoutOut.legend = undefined;
77740
78042
 
77741
- function coerce(attr, dflt) {
77742
- return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
77743
- }
78043
+ if(showLegend === false && !containerIn.uirevision) return;
77744
78044
 
77745
78045
  coerce('uirevision', layoutOut.uirevision);
77746
78046
 
@@ -77802,7 +78102,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
77802
78102
  }
77803
78103
  };
77804
78104
 
77805
- },{"../../lib":246,"../../plot_api/plot_template":282,"../../plots/layout_attributes":328,"../../registry":340,"./attributes":164,"./helpers":170}],167:[function(_dereq_,module,exports){
78105
+ },{"../../lib":246,"../../plot_api/plot_template":282,"../../plots/attributes":289,"../../plots/layout_attributes":328,"../../registry":340,"./attributes":164,"./helpers":170}],167:[function(_dereq_,module,exports){
77806
78106
  'use strict';
77807
78107
 
77808
78108
  var d3 = _dereq_('@plotly/d3');
@@ -86254,8 +86554,10 @@ function draw(gd, titleClass, options) {
86254
86554
 
86255
86555
  var elShouldExist = txt || editable;
86256
86556
 
86557
+ var hColorbarMoveTitle;
86257
86558
  if(!group) {
86258
86559
  group = Lib.ensureSingle(fullLayout._infolayer, 'g', 'g-' + titleClass);
86560
+ hColorbarMoveTitle = fullLayout._hColorbarMoveTitle;
86259
86561
  }
86260
86562
 
86261
86563
  var el = group.selectAll('text')
@@ -86279,13 +86581,17 @@ function draw(gd, titleClass, options) {
86279
86581
  function drawTitle(titleEl) {
86280
86582
  var transformVal;
86281
86583
 
86584
+ if(!transform && hColorbarMoveTitle) {
86585
+ transform = {};
86586
+ }
86587
+
86282
86588
  if(transform) {
86283
86589
  transformVal = '';
86284
86590
  if(transform.rotate) {
86285
86591
  transformVal += 'rotate(' + [transform.rotate, attributes.x, attributes.y] + ')';
86286
86592
  }
86287
- if(transform.offset) {
86288
- transformVal += strTranslate(0, transform.offset);
86593
+ if(transform.offset || hColorbarMoveTitle) {
86594
+ transformVal += strTranslate(0, (transform.offset || 0) - (hColorbarMoveTitle || 0));
86289
86595
  }
86290
86596
  } else {
86291
86597
  transformVal = null;
@@ -98228,7 +98534,7 @@ function cleanDeprecatedAttributeKeys(aobj) {
98228
98534
  if((key === 'title' || oldAxisTitleRegex.test(key) || colorbarRegex.test(key)) &&
98229
98535
  (typeof value === 'string' || typeof value === 'number')) {
98230
98536
  replace(key, key.replace('title', 'title.text'));
98231
- } else if(key.indexOf('titlefont') > -1) {
98537
+ } else if(key.indexOf('titlefont') > -1 && key.indexOf('grouptitlefont') === -1) {
98232
98538
  replace(key, key.replace('titlefont', 'title.font'));
98233
98539
  } else if(key.indexOf('titleposition') > -1) {
98234
98540
  replace(key, key.replace('titleposition', 'title.position'));
@@ -116096,6 +116402,9 @@ module.exports = function(opts) {
116096
116402
  // TODO - that's uber hacky... better solution?
116097
116403
  };
116098
116404
 
116405
+ if(opts.autoSize) attrs.size.dflt = 'auto';
116406
+ if(opts.autoColor) attrs.color.dflt = 'auto';
116407
+
116099
116408
  if(opts.arrayOk) {
116100
116409
  attrs.family.arrayOk = true;
116101
116410
  attrs.size.arrayOk = true;
@@ -116455,6 +116764,7 @@ module.exports = {
116455
116764
  valType: 'boolean',
116456
116765
  editType: 'legend',
116457
116766
  },
116767
+
116458
116768
  colorway: {
116459
116769
  valType: 'colorlist',
116460
116770
  dflt: colorAttrs.defaults,
@@ -119837,13 +120147,7 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac
119837
120147
  );
119838
120148
 
119839
120149
  coerce('legendgroup');
119840
- var titleText = coerce('legendgrouptitle.text');
119841
- if(titleText) {
119842
- Lib.coerceFont(coerce, 'legendgrouptitle.font', Lib.extendFlat({}, layout.font, {
119843
- size: Math.round(layout.font.size * 1.1) // default to larger font size
119844
- }));
119845
- }
119846
-
120150
+ coerce('legendgrouptitle.text');
119847
120151
  coerce('legendrank');
119848
120152
 
119849
120153
  traceOut._dfltShowLegend = true;
@@ -119991,16 +120295,14 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut, formatObj) {
119991
120295
 
119992
120296
  coerce('autotypenumbers');
119993
120297
 
119994
- var globalFont = Lib.coerceFont(coerce, 'font');
119995
-
119996
- coerce('title.text', layoutOut._dfltTitle.plot);
120298
+ var font = Lib.coerceFont(coerce, 'font');
120299
+ var fontSize = font.size;
119997
120300
 
119998
- Lib.coerceFont(coerce, 'title.font', {
119999
- family: globalFont.family,
120000
- size: Math.round(globalFont.size * 1.4),
120001
- color: globalFont.color
120002
- });
120301
+ Lib.coerceFont(coerce, 'title.font', Lib.extendFlat({}, font, {
120302
+ size: Math.round(fontSize * 1.4)
120303
+ }));
120003
120304
 
120305
+ coerce('title.text', layoutOut._dfltTitle.plot);
120004
120306
  coerce('title.xref');
120005
120307
  coerce('title.yref');
120006
120308
  coerce('title.x');
@@ -129537,7 +129839,7 @@ function getSortFunc(opts, d2c) {
129537
129839
  'use strict';
129538
129840
 
129539
129841
  // package version injected by `npm run preprocess`
129540
- exports.version = '2.7.0';
129842
+ exports.version = '2.8.0';
129541
129843
 
129542
129844
  },{}]},{},[9])(9)
129543
129845
  });