plotly.js 2.6.3 → 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +3 -3
  3. package/dist/README.md +26 -26
  4. package/dist/plot-schema.json +1015 -407
  5. package/dist/plotly-basic.js +533 -197
  6. package/dist/plotly-basic.min.js +4 -4
  7. package/dist/plotly-cartesian.js +996 -343
  8. package/dist/plotly-cartesian.min.js +3 -3
  9. package/dist/plotly-finance.js +583 -199
  10. package/dist/plotly-finance.min.js +4 -4
  11. package/dist/plotly-geo-assets.js +2 -2
  12. package/dist/plotly-geo.js +529 -195
  13. package/dist/plotly-geo.min.js +4 -4
  14. package/dist/plotly-gl2d.js +545 -196
  15. package/dist/plotly-gl2d.min.js +2 -2
  16. package/dist/plotly-gl3d.js +529 -195
  17. package/dist/plotly-gl3d.min.js +8 -8
  18. package/dist/plotly-mapbox.js +535 -198
  19. package/dist/plotly-mapbox.min.js +2 -2
  20. package/dist/plotly-strict.js +1220 -564
  21. package/dist/plotly-strict.min.js +3 -3
  22. package/dist/plotly-with-meta.js +1312 -626
  23. package/dist/plotly.js +1274 -618
  24. package/dist/plotly.min.js +10 -10
  25. package/package.json +9 -9
  26. package/src/components/colorbar/attributes.js +29 -20
  27. package/src/components/colorbar/defaults.js +30 -8
  28. package/src/components/colorbar/draw.js +374 -128
  29. package/src/components/drawing/index.js +6 -3
  30. package/src/components/fx/hover.js +5 -2
  31. package/src/components/fx/hoverlabel_defaults.js +4 -2
  32. package/src/components/fx/layout_attributes.js +14 -4
  33. package/src/components/fx/layout_defaults.js +2 -0
  34. package/src/components/legend/attributes.js +7 -0
  35. package/src/components/legend/defaults.js +24 -7
  36. package/src/components/titles/index.js +8 -2
  37. package/src/plot_api/plot_api.js +38 -9
  38. package/src/plots/font_attributes.js +3 -0
  39. package/src/plots/layout_attributes.js +1 -0
  40. package/src/plots/mapbox/mapbox.js +6 -3
  41. package/src/plots/plots.js +7 -15
  42. package/src/traces/bar/plot.js +1 -1
  43. package/src/traces/contour/attributes.js +12 -0
  44. package/src/traces/contour/defaults.js +9 -1
  45. package/src/traces/heatmap/attributes.js +16 -0
  46. package/src/traces/heatmap/defaults.js +2 -0
  47. package/src/traces/heatmap/label_defaults.js +13 -0
  48. package/src/traces/heatmap/plot.js +205 -4
  49. package/src/traces/histogram/attributes.js +40 -0
  50. package/src/traces/histogram/defaults.js +11 -0
  51. package/src/traces/histogram2d/attributes.js +8 -0
  52. package/src/traces/histogram2d/defaults.js +4 -0
  53. package/src/traces/histogram2dcontour/attributes.js +3 -1
  54. package/src/traces/histogram2dcontour/defaults.js +8 -1
  55. package/src/traces/pie/calc.js +3 -1
  56. package/src/version.js +1 -1
  57. package/tasks/test_mock.js +1 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * plotly.js (finance) v2.6.3
2
+ * plotly.js (finance) v2.8.1
3
3
  * Copyright 2012-2021, Plotly, Inc.
4
4
  * All rights reserved.
5
5
  * Licensed under the MIT license
@@ -22784,13 +22784,11 @@ var overrideAll = _dereq_('../../plot_api/edit_types').overrideAll;
22784
22784
 
22785
22785
 
22786
22786
  module.exports = overrideAll({
22787
- // TODO: only right is supported currently
22788
- // orient: {
22789
- // valType: 'enumerated',
22790
- // values: ['left', 'right', 'top', 'bottom'],
22791
- // dflt: 'right',
22792
- //
22793
- // },
22787
+ orientation: {
22788
+ valType: 'enumerated',
22789
+ values: ['h', 'v'],
22790
+ dflt: 'v',
22791
+ },
22794
22792
  thicknessmode: {
22795
22793
  valType: 'enumerated',
22796
22794
  values: ['fraction', 'pixels'],
@@ -22813,14 +22811,12 @@ module.exports = overrideAll({
22813
22811
  },
22814
22812
  x: {
22815
22813
  valType: 'number',
22816
- dflt: 1.02,
22817
22814
  min: -2,
22818
22815
  max: 3,
22819
22816
  },
22820
22817
  xanchor: {
22821
22818
  valType: 'enumerated',
22822
22819
  values: ['left', 'center', 'right'],
22823
- dflt: 'left',
22824
22820
  },
22825
22821
  xpad: {
22826
22822
  valType: 'number',
@@ -22829,14 +22825,12 @@ module.exports = overrideAll({
22829
22825
  },
22830
22826
  y: {
22831
22827
  valType: 'number',
22832
- dflt: 0.5,
22833
22828
  min: -2,
22834
22829
  max: 3,
22835
22830
  },
22836
22831
  yanchor: {
22837
22832
  valType: 'enumerated',
22838
22833
  values: ['top', 'middle', 'bottom'],
22839
- dflt: 'middle',
22840
22834
  },
22841
22835
  ypad: {
22842
22836
  valType: 'number',
@@ -22868,15 +22862,21 @@ module.exports = overrideAll({
22868
22862
  ticks: extendFlat({}, axesAttrs.ticks, {dflt: ''}),
22869
22863
  ticklabeloverflow: extendFlat({}, axesAttrs.ticklabeloverflow, {
22870
22864
  }),
22865
+
22866
+ // ticklabelposition: not used directly, as values depend on orientation
22867
+ // left/right options are for x axes, and top/bottom options are for y axes
22871
22868
  ticklabelposition: {
22872
22869
  valType: 'enumerated',
22873
22870
  values: [
22874
22871
  'outside', 'inside',
22875
22872
  'outside top', 'inside top',
22873
+ 'outside left', 'inside left',
22874
+ 'outside right', 'inside right',
22876
22875
  'outside bottom', 'inside bottom'
22877
22876
  ],
22878
22877
  dflt: 'outside',
22879
22878
  },
22879
+
22880
22880
  ticklen: axesAttrs.ticklen,
22881
22881
  tickwidth: axesAttrs.tickwidth,
22882
22882
  tickcolor: axesAttrs.tickcolor,
@@ -22903,7 +22903,6 @@ module.exports = overrideAll({
22903
22903
  side: {
22904
22904
  valType: 'enumerated',
22905
22905
  values: ['right', 'top', 'bottom'],
22906
- dflt: 'top',
22907
22906
  }
22908
22907
  },
22909
22908
 
@@ -22962,23 +22961,30 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
22962
22961
  return Lib.coerce(colorbarIn, colorbarOut, attributes, attr, dflt);
22963
22962
  }
22964
22963
 
22964
+ var margin = layout.margin || {t: 0, b: 0, l: 0, r: 0};
22965
+ var w = layout.width - margin.l - margin.r;
22966
+ var h = layout.height - margin.t - margin.b;
22967
+
22968
+ var orientation = coerce('orientation');
22969
+ var isVertical = orientation === 'v';
22970
+
22965
22971
  var thicknessmode = coerce('thicknessmode');
22966
22972
  coerce('thickness', (thicknessmode === 'fraction') ?
22967
- 30 / (layout.width - layout.margin.l - layout.margin.r) :
22973
+ 30 / (isVertical ? w : h) :
22968
22974
  30
22969
22975
  );
22970
22976
 
22971
22977
  var lenmode = coerce('lenmode');
22972
22978
  coerce('len', (lenmode === 'fraction') ?
22973
22979
  1 :
22974
- layout.height - layout.margin.t - layout.margin.b
22980
+ isVertical ? h : w
22975
22981
  );
22976
22982
 
22977
- coerce('x');
22978
- coerce('xanchor');
22983
+ coerce('x', isVertical ? 1.02 : 0.5);
22984
+ coerce('xanchor', isVertical ? 'left' : 'center');
22979
22985
  coerce('xpad');
22980
- coerce('y');
22981
- coerce('yanchor');
22986
+ coerce('y', isVertical ? 0.5 : 1.02);
22987
+ coerce('yanchor', isVertical ? 'middle' : 'bottom');
22982
22988
  coerce('ypad');
22983
22989
  Lib.noneOrAll(colorbarIn, colorbarOut, ['x', 'y']);
22984
22990
 
@@ -22988,7 +22994,22 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
22988
22994
  coerce('borderwidth');
22989
22995
  coerce('bgcolor');
22990
22996
 
22991
- var ticklabelposition = coerce('ticklabelposition');
22997
+ var ticklabelposition = Lib.coerce(colorbarIn, colorbarOut, {
22998
+ ticklabelposition: {
22999
+ valType: 'enumerated',
23000
+ dflt: 'outside',
23001
+ values: isVertical ? [
23002
+ 'outside', 'inside',
23003
+ 'outside top', 'inside top',
23004
+ 'outside bottom', 'inside bottom'
23005
+ ] : [
23006
+ 'outside', 'inside',
23007
+ 'outside left', 'inside left',
23008
+ 'outside right', 'inside right'
23009
+ ]
23010
+ }
23011
+ }, 'ticklabelposition');
23012
+
22992
23013
  coerce('ticklabeloverflow', ticklabelposition.indexOf('inside') !== -1 ? 'hide past domain' : 'hide past div');
22993
23014
 
22994
23015
  handleTickValueDefaults(colorbarIn, colorbarOut, coerce, 'linear');
@@ -23010,7 +23031,7 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
23010
23031
  size: Lib.bigFont(tickFont.size)
23011
23032
  });
23012
23033
  Lib.coerceFont(coerce, 'title.font', dfltTitleFont);
23013
- coerce('title.side');
23034
+ coerce('title.side', isVertical ? 'top' : 'right');
23014
23035
  };
23015
23036
 
23016
23037
  },{"../../lib":242,"../../plot_api/plot_template":278,"../../plots/cartesian/prefix_suffix_defaults":308,"../../plots/cartesian/tick_label_defaults":313,"../../plots/cartesian/tick_mark_defaults":314,"../../plots/cartesian/tick_value_defaults":315,"./attributes":112}],115:[function(_dereq_,module,exports){
@@ -23183,18 +23204,20 @@ function makeColorBarData(gd) {
23183
23204
  }
23184
23205
 
23185
23206
  function drawColorBar(g, opts, gd) {
23207
+ var isVertical = opts.orientation === 'v';
23186
23208
  var len = opts.len;
23187
23209
  var lenmode = opts.lenmode;
23188
23210
  var thickness = opts.thickness;
23189
23211
  var thicknessmode = opts.thicknessmode;
23190
23212
  var outlinewidth = opts.outlinewidth;
23191
23213
  var borderwidth = opts.borderwidth;
23214
+ var bgcolor = opts.bgcolor;
23192
23215
  var xanchor = opts.xanchor;
23193
23216
  var yanchor = opts.yanchor;
23194
23217
  var xpad = opts.xpad;
23195
23218
  var ypad = opts.ypad;
23196
23219
  var optsX = opts.x;
23197
- var optsY = opts.y;
23220
+ var optsY = isVertical ? opts.y : 1 - opts.y;
23198
23221
 
23199
23222
  var fullLayout = gd._fullLayout;
23200
23223
  var gs = fullLayout._size;
@@ -23225,23 +23248,35 @@ function drawColorBar(g, opts, gd) {
23225
23248
  // when the colorbar itself is pushing the margins.
23226
23249
  // but then the fractional size is calculated based on the
23227
23250
  // actual graph size, so that the axes will size correctly.
23228
- var thickPx = Math.round(thickness * (thicknessmode === 'fraction' ? gs.w : 1));
23229
- var thickFrac = thickPx / gs.w;
23230
- var lenPx = Math.round(len * (lenmode === 'fraction' ? gs.h : 1));
23231
- var lenFrac = lenPx / gs.h;
23232
- var xpadFrac = xpad / gs.w;
23233
- var yExtraPx = (borderwidth + outlinewidth) / 2;
23234
- var ypadFrac = ypad / gs.h;
23251
+ var thickPx = Math.round(thickness * (thicknessmode === 'fraction' ? (isVertical ? gs.w : gs.h) : 1));
23252
+ var thickFrac = thickPx / (isVertical ? gs.w : gs.h);
23253
+ var lenPx = Math.round(len * (lenmode === 'fraction' ? (isVertical ? gs.h : gs.w) : 1));
23254
+ var lenFrac = lenPx / (isVertical ? gs.h : gs.w);
23235
23255
 
23236
23256
  // x positioning: do it initially just for left anchor,
23237
23257
  // then fix at the end (since we don't know the width yet)
23238
- var uPx = Math.round(optsX * gs.w + xpad);
23239
- // for dragging... this is getting a little muddled...
23240
- var uFrac = optsX - thickFrac * ({center: 0.5, right: 1}[xanchor] || 0);
23258
+ var uPx = Math.round(isVertical ?
23259
+ optsX * gs.w + xpad :
23260
+ optsY * gs.h + ypad
23261
+ );
23241
23262
 
23242
- // y positioning we can do correctly from the start
23243
- var vFrac = optsY + lenFrac * (({top: -0.5, bottom: 0.5}[yanchor] || 0) - 0.5);
23244
- var vPx = Math.round(gs.h * (1 - vFrac));
23263
+ var xRatio = {center: 0.5, right: 1}[xanchor] || 0;
23264
+ var yRatio = {top: 1, middle: 0.5}[yanchor] || 0;
23265
+
23266
+ // for dragging... this is getting a little muddled...
23267
+ var uFrac = isVertical ?
23268
+ optsX - xRatio * thickFrac :
23269
+ optsY - yRatio * thickFrac;
23270
+
23271
+ // y/x positioning (for v/h) we can do correctly from the start
23272
+ var vFrac = isVertical ?
23273
+ optsY - yRatio * lenFrac :
23274
+ optsX - xRatio * lenFrac;
23275
+
23276
+ var vPx = Math.round(isVertical ?
23277
+ gs.h * (1 - vFrac) :
23278
+ gs.w * vFrac
23279
+ );
23245
23280
 
23246
23281
  // stash a few things for makeEditable
23247
23282
  opts._lenFrac = lenFrac;
@@ -23254,12 +23289,23 @@ function drawColorBar(g, opts, gd) {
23254
23289
 
23255
23290
  // position can't go in through supplyDefaults
23256
23291
  // because that restricts it to [0,1]
23257
- ax.position = optsX + xpadFrac + thickFrac;
23292
+ ax.position = thickFrac + (isVertical ?
23293
+ optsX + xpad / gs.w :
23294
+ optsY + ypad / gs.h
23295
+ );
23296
+
23297
+ var topOrBottom = ['top', 'bottom'].indexOf(titleSide) !== -1;
23298
+
23299
+ if(isVertical && topOrBottom) {
23300
+ ax.title.side = titleSide;
23301
+ ax.titlex = optsX + xpad / gs.w;
23302
+ ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypad / gs.h : ypad / gs.h);
23303
+ }
23258
23304
 
23259
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
23305
+ if(!isVertical && !topOrBottom) {
23260
23306
  ax.title.side = titleSide;
23261
- ax.titlex = optsX + xpadFrac;
23262
- ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
23307
+ ax.titley = optsY + ypad / gs.h;
23308
+ ax.titlex = vFrac + xpad / gs.w; // right side
23263
23309
  }
23264
23310
 
23265
23311
  if(line.color && opts.tickmode === 'auto') {
@@ -23284,9 +23330,12 @@ function drawColorBar(g, opts, gd) {
23284
23330
 
23285
23331
  // set domain after init, because we may want to
23286
23332
  // allow it outside [0,1]
23287
- ax.domain = [
23288
- vFrac + ypadFrac,
23289
- vFrac + lenFrac - ypadFrac
23333
+ ax.domain = isVertical ? [
23334
+ vFrac + ypad / gs.h,
23335
+ vFrac + lenFrac - ypad / gs.h
23336
+ ] : [
23337
+ vFrac + xpad / gs.w,
23338
+ vFrac + lenFrac - xpad / gs.w
23290
23339
  ];
23291
23340
 
23292
23341
  ax.setScale();
@@ -23296,9 +23345,13 @@ function drawColorBar(g, opts, gd) {
23296
23345
  var titleCont = g.select('.' + cn.cbtitleunshift)
23297
23346
  .attr('transform', strTranslate(-Math.round(gs.l), -Math.round(gs.t)));
23298
23347
 
23348
+ var ticklabelposition = ax.ticklabelposition;
23349
+ var titleFontSize = ax.title.font.size;
23350
+
23299
23351
  var axLayer = g.select('.' + cn.cbaxis);
23300
23352
  var titleEl;
23301
23353
  var titleHeight = 0;
23354
+ var titleWidth = 0;
23302
23355
 
23303
23356
  function drawTitle(titleClass, titleOpts) {
23304
23357
  var dfltTitleOpts = {
@@ -23323,54 +23376,98 @@ function drawColorBar(g, opts, gd) {
23323
23376
  }
23324
23377
 
23325
23378
  function drawDummyTitle() {
23326
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
23327
- // draw the title so we know how much room it needs
23328
- // when we squish the axis. This one only applies to
23329
- // top or bottom titles, not right side.
23330
- var x = gs.l + (optsX + xpadFrac) * gs.w;
23331
- var fontSize = ax.title.font.size;
23332
- var y;
23379
+ // draw the title so we know how much room it needs
23380
+ // when we squish the axis.
23381
+ // On vertical colorbars this only applies to top or bottom titles, not right side.
23382
+ // On horizontal colorbars this only applies to right, etc.
23383
+
23384
+ if(
23385
+ (isVertical && topOrBottom) ||
23386
+ (!isVertical && !topOrBottom)
23387
+ ) {
23388
+ var x, y;
23333
23389
 
23334
23390
  if(titleSide === 'top') {
23335
- y = (1 - (vFrac + lenFrac - ypadFrac)) * gs.h +
23336
- gs.t + 3 + fontSize * 0.75;
23337
- } else {
23338
- y = (1 - (vFrac + ypadFrac)) * gs.h +
23339
- gs.t - 3 - fontSize * 0.25;
23391
+ x = xpad + gs.l + gs.w * optsX;
23392
+ y = ypad + gs.t + gs.h * (1 - vFrac - lenFrac) + 3 + titleFontSize * 0.75;
23393
+ }
23394
+
23395
+ if(titleSide === 'bottom') {
23396
+ x = xpad + gs.l + gs.w * optsX;
23397
+ y = ypad + gs.t + gs.h * (1 - vFrac) - 3 - titleFontSize * 0.25;
23340
23398
  }
23399
+
23400
+ if(titleSide === 'right') {
23401
+ y = ypad + gs.t + gs.h * optsY + 3 + titleFontSize * 0.75;
23402
+ x = xpad + gs.l + gs.w * vFrac;
23403
+ }
23404
+
23341
23405
  drawTitle(ax._id + 'title', {
23342
- attributes: {x: x, y: y, 'text-anchor': 'start'}
23406
+ attributes: {x: x, y: y, 'text-anchor': isVertical ? 'start' : 'middle'}
23343
23407
  });
23344
23408
  }
23345
23409
  }
23346
23410
 
23347
23411
  function drawCbTitle() {
23348
- if(['top', 'bottom'].indexOf(titleSide) === -1) {
23349
- var fontSize = ax.title.font.size;
23350
- var y = ax._offset + ax._length / 2;
23351
- var x = gs.l + (ax.position || 0) * gs.w + ((ax.side === 'right') ?
23352
- 10 + fontSize * ((ax.showticklabels ? 1 : 0.5)) :
23353
- -10 - fontSize * ((ax.showticklabels ? 0.5 : 0)));
23354
-
23355
- // the 'h' + is a hack to get around the fact that
23356
- // convertToTspans rotates any 'y...' class by 90 degrees.
23357
- // TODO: find a better way to control this.
23358
- drawTitle('h' + ax._id + 'title', {
23412
+ if(
23413
+ (isVertical && !topOrBottom) ||
23414
+ (!isVertical && topOrBottom)
23415
+ ) {
23416
+ var pos = ax.position || 0;
23417
+ var mid = ax._offset + ax._length / 2;
23418
+ var x, y;
23419
+
23420
+ if(titleSide === 'right') {
23421
+ y = mid;
23422
+ x = gs.l + gs.w * pos + 10 + titleFontSize * (
23423
+ ax.showticklabels ? 1 : 0.5
23424
+ );
23425
+ } else {
23426
+ x = mid;
23427
+
23428
+ if(titleSide === 'bottom') {
23429
+ y = gs.t + gs.h * pos + 10 + (
23430
+ ticklabelposition.indexOf('inside') === -1 ?
23431
+ ax.tickfont.size :
23432
+ 0
23433
+ ) + (
23434
+ ax.ticks !== 'intside' ?
23435
+ opts.ticklen || 0 :
23436
+ 0
23437
+ );
23438
+ }
23439
+
23440
+ if(titleSide === 'top') {
23441
+ var nlines = title.text.split('<br>').length;
23442
+ y = gs.t + gs.h * pos + 10 - thickPx - LINE_SPACING * titleFontSize * nlines;
23443
+ }
23444
+ }
23445
+
23446
+ drawTitle((isVertical ?
23447
+ // the 'h' + is a hack to get around the fact that
23448
+ // convertToTspans rotates any 'y...' class by 90 degrees.
23449
+ // TODO: find a better way to control this.
23450
+ 'h' :
23451
+ 'v'
23452
+ ) + ax._id + 'title', {
23359
23453
  avoid: {
23360
23454
  selection: d3.select(gd).selectAll('g.' + ax._id + 'tick'),
23361
23455
  side: titleSide,
23362
- offsetLeft: gs.l,
23363
- offsetTop: 0,
23364
- maxShift: fullLayout.width
23456
+ offsetTop: isVertical ? 0 : gs.t,
23457
+ offsetLeft: isVertical ? gs.l : 0,
23458
+ maxShift: isVertical ? fullLayout.width : fullLayout.height
23365
23459
  },
23366
23460
  attributes: {x: x, y: y, 'text-anchor': 'middle'},
23367
- transform: {rotate: '-90', offset: 0}
23461
+ transform: {rotate: isVertical ? -90 : 0, offset: 0}
23368
23462
  });
23369
23463
  }
23370
23464
  }
23371
23465
 
23372
23466
  function drawAxis() {
23373
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
23467
+ if(
23468
+ (!isVertical && !topOrBottom) ||
23469
+ (isVertical && topOrBottom)
23470
+ ) {
23374
23471
  // squish the axis top to make room for the title
23375
23472
  var titleGroup = g.select('.' + cn.cbtitle);
23376
23473
  var titleText = titleGroup.select('text');
@@ -23382,39 +23479,63 @@ function drawColorBar(g, opts, gd) {
23382
23479
  if(titleText.node()) {
23383
23480
  lineSize = parseInt(titleText.node().style.fontSize, 10) * LINE_SPACING;
23384
23481
  }
23482
+
23483
+ var bb;
23385
23484
  if(mathJaxNode) {
23386
- titleHeight = Drawing.bBox(mathJaxNode).height;
23485
+ bb = Drawing.bBox(mathJaxNode);
23486
+ titleWidth = bb.width;
23487
+ titleHeight = bb.height;
23387
23488
  if(titleHeight > lineSize) {
23388
23489
  // not entirely sure how mathjax is doing
23389
23490
  // vertical alignment, but this seems to work.
23390
23491
  titleTrans[1] -= (titleHeight - lineSize) / 2;
23391
23492
  }
23392
23493
  } else if(titleText.node() && !titleText.classed(cn.jsPlaceholder)) {
23393
- titleHeight = Drawing.bBox(titleText.node()).height;
23494
+ bb = Drawing.bBox(titleText.node());
23495
+ titleWidth = bb.width;
23496
+ titleHeight = bb.height;
23394
23497
  }
23395
- if(titleHeight) {
23396
- // buffer btwn colorbar and title
23397
- // TODO: configurable
23398
- titleHeight += 5;
23399
23498
 
23400
- if(titleSide === 'top') {
23401
- ax.domain[1] -= titleHeight / gs.h;
23402
- titleTrans[1] *= -1;
23403
- } else {
23404
- ax.domain[0] += titleHeight / gs.h;
23405
- var nlines = svgTextUtils.lineCount(titleText);
23406
- titleTrans[1] += (1 - nlines) * lineSize;
23499
+ if(isVertical) {
23500
+ if(titleHeight) {
23501
+ // buffer btwn colorbar and title
23502
+ // TODO: configurable
23503
+ titleHeight += 5;
23504
+
23505
+ if(titleSide === 'top') {
23506
+ ax.domain[1] -= titleHeight / gs.h;
23507
+ titleTrans[1] *= -1;
23508
+ } else {
23509
+ ax.domain[0] += titleHeight / gs.h;
23510
+ var nlines = svgTextUtils.lineCount(titleText);
23511
+ titleTrans[1] += (1 - nlines) * lineSize;
23512
+ }
23513
+
23514
+ titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
23515
+ ax.setScale();
23407
23516
  }
23517
+ } else { // horizontal colorbars
23518
+ if(titleWidth) {
23519
+ if(titleSide === 'right') {
23520
+ ax.domain[0] += (titleWidth + titleFontSize / 2) / gs.w;
23521
+ }
23408
23522
 
23409
- titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
23410
- ax.setScale();
23523
+ titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
23524
+ ax.setScale();
23525
+ }
23411
23526
  }
23412
23527
  }
23413
23528
 
23414
23529
  g.selectAll('.' + cn.cbfills + ',.' + cn.cblines)
23415
- .attr('transform', strTranslate(0, Math.round(gs.h * (1 - ax.domain[1]))));
23530
+ .attr('transform', isVertical ?
23531
+ strTranslate(0, Math.round(gs.h * (1 - ax.domain[1]))) :
23532
+ strTranslate(Math.round(gs.w * ax.domain[0]), 0)
23533
+ );
23416
23534
 
23417
- axLayer.attr('transform', strTranslate(0, Math.round(-gs.t)));
23535
+ axLayer.attr('transform', isVertical ?
23536
+ strTranslate(0, Math.round(-gs.t)) :
23537
+ strTranslate(Math.round(-gs.l), 0)
23538
+ );
23418
23539
 
23419
23540
  var fills = g.select('.' + cn.cbfills)
23420
23541
  .selectAll('rect.' + cn.cbfill)
@@ -23440,20 +23561,22 @@ function drawColorBar(g, opts, gd) {
23440
23561
 
23441
23562
  // offset the side adjoining the next rectangle so they
23442
23563
  // overlap, to prevent antialiasing gaps
23443
- z[1] = Lib.constrain(z[1] + (z[1] > z[0]) ? 1 : -1, zBounds[0], zBounds[1]);
23444
-
23564
+ if(isVertical) {
23565
+ z[1] = Lib.constrain(z[1] + (z[1] > z[0]) ? 1 : -1, zBounds[0], zBounds[1]);
23566
+ } /* else {
23567
+ // TODO: horizontal case
23568
+ } */
23445
23569
 
23446
23570
  // Colorbar cannot currently support opacities so we
23447
23571
  // use an opaque fill even when alpha channels present
23448
- var fillEl = d3.select(this).attr({
23449
- x: uPx,
23450
- width: Math.max(thickPx, 2),
23451
- y: d3.min(z),
23452
- height: Math.max(d3.max(z) - d3.min(z), 2),
23453
- });
23572
+ var fillEl = d3.select(this)
23573
+ .attr(isVertical ? 'x' : 'y', uPx)
23574
+ .attr(isVertical ? 'y' : 'x', d3.min(z))
23575
+ .attr(isVertical ? 'width' : 'height', Math.max(thickPx, 2))
23576
+ .attr(isVertical ? 'height' : 'width', Math.max(d3.max(z) - d3.min(z), 2));
23454
23577
 
23455
23578
  if(opts._fillgradient) {
23456
- Drawing.gradient(fillEl, gd, opts._id, 'vertical', opts._fillgradient, 'fill');
23579
+ Drawing.gradient(fillEl, gd, opts._id, isVertical ? 'vertical' : 'horizontalreversed', opts._fillgradient, 'fill');
23457
23580
  } else {
23458
23581
  // tinycolor can't handle exponents and
23459
23582
  // at this scale, removing it makes no difference.
@@ -23469,9 +23592,15 @@ function drawColorBar(g, opts, gd) {
23469
23592
  .classed(cn.cbline, true);
23470
23593
  lines.exit().remove();
23471
23594
  lines.each(function(d) {
23595
+ var a = uPx;
23596
+ var b = (Math.round(ax.c2p(d)) + (line.width / 2) % 1);
23597
+
23472
23598
  d3.select(this)
23473
- .attr('d', 'M' + uPx + ',' +
23474
- (Math.round(ax.c2p(d)) + (line.width / 2) % 1) + 'h' + thickPx)
23599
+ .attr('d', 'M' +
23600
+ (isVertical ? a + ',' + b : b + ',' + a) +
23601
+ (isVertical ? 'h' : 'v') +
23602
+ thickPx
23603
+ )
23475
23604
  .call(Drawing.lineGroupStyle, line.width, lineColormap(d), line.dash);
23476
23605
  });
23477
23606
 
@@ -23504,82 +23633,211 @@ function drawColorBar(g, opts, gd) {
23504
23633
  // TODO: why are we redrawing multiple times now with this?
23505
23634
  // I guess autoMargin doesn't like being post-promise?
23506
23635
  function positionCB() {
23636
+ var bb;
23507
23637
  var innerThickness = thickPx + outlinewidth / 2;
23508
- if(ax.ticklabelposition.indexOf('inside') === -1) {
23509
- innerThickness += Drawing.bBox(axLayer.node()).width;
23638
+ if(ticklabelposition.indexOf('inside') === -1) {
23639
+ bb = Drawing.bBox(axLayer.node());
23640
+ innerThickness += isVertical ? bb.width : bb.height;
23510
23641
  }
23511
23642
 
23512
23643
  titleEl = titleCont.select('text');
23513
23644
 
23645
+ var titleWidth = 0;
23646
+
23647
+ var topSideVertical = isVertical && titleSide === 'top';
23648
+ var rightSideHorizontal = !isVertical && titleSide === 'right';
23649
+
23650
+ var moveY = 0;
23651
+
23514
23652
  if(titleEl.node() && !titleEl.classed(cn.jsPlaceholder)) {
23653
+ var _titleHeight;
23654
+
23515
23655
  var mathJaxNode = titleCont.select('.h' + ax._id + 'title-math-group').node();
23516
- var titleWidth;
23517
- if(mathJaxNode && ['top', 'bottom'].indexOf(titleSide) !== -1) {
23518
- titleWidth = Drawing.bBox(mathJaxNode).width;
23656
+ if(mathJaxNode && (
23657
+ (isVertical && topOrBottom) ||
23658
+ (!isVertical && !topOrBottom)
23659
+ )) {
23660
+ bb = Drawing.bBox(mathJaxNode);
23661
+ titleWidth = bb.width;
23662
+ _titleHeight = bb.height;
23519
23663
  } else {
23520
23664
  // note: the formula below works for all title sides,
23521
23665
  // (except for top/bottom mathjax, above)
23522
23666
  // but the weird gs.l is because the titleunshift
23523
23667
  // transform gets removed by Drawing.bBox
23524
- titleWidth = Drawing.bBox(titleCont.node()).right - uPx - gs.l;
23668
+ bb = Drawing.bBox(titleCont.node());
23669
+ titleWidth = bb.right - gs.l - (isVertical ? uPx : vPx);
23670
+ _titleHeight = bb.bottom - gs.t - (isVertical ? vPx : uPx);
23671
+
23672
+ if(
23673
+ !isVertical && titleSide === 'top'
23674
+ ) {
23675
+ innerThickness += bb.height;
23676
+ moveY = bb.height;
23677
+ }
23525
23678
  }
23526
- innerThickness = Math.max(innerThickness, titleWidth);
23679
+
23680
+ if(rightSideHorizontal) {
23681
+ titleEl.attr('transform', strTranslate(titleWidth / 2 + titleFontSize / 2, 0));
23682
+
23683
+ titleWidth *= 2;
23684
+ }
23685
+
23686
+ innerThickness = Math.max(innerThickness,
23687
+ isVertical ? titleWidth : _titleHeight
23688
+ );
23527
23689
  }
23528
23690
 
23529
- var outerThickness = 2 * xpad + innerThickness + borderwidth + outlinewidth / 2;
23691
+ var outerThickness = (isVertical ?
23692
+ xpad :
23693
+ ypad
23694
+ ) * 2 + innerThickness + borderwidth + outlinewidth / 2;
23530
23695
 
23531
- g.select('.' + cn.cbbg).attr({
23532
- x: uPx - xpad - (borderwidth + outlinewidth) / 2,
23533
- y: vPx - lenPx - yExtraPx,
23534
- width: Math.max(outerThickness, 2),
23535
- height: Math.max(lenPx + 2 * yExtraPx, 2)
23536
- })
23537
- .call(Color.fill, opts.bgcolor)
23696
+ var hColorbarMoveTitle = 0;
23697
+ if(!isVertical && title.text && yanchor === 'bottom' && optsY <= 0) {
23698
+ hColorbarMoveTitle = outerThickness / 2;
23699
+
23700
+ outerThickness += hColorbarMoveTitle;
23701
+ moveY += hColorbarMoveTitle;
23702
+ }
23703
+ fullLayout._hColorbarMoveTitle = hColorbarMoveTitle;
23704
+ fullLayout._hColorbarMoveCBTitle = moveY;
23705
+
23706
+ var extraW = borderwidth + outlinewidth;
23707
+
23708
+ g.select('.' + cn.cbbg)
23709
+ .attr('x', (isVertical ? uPx : vPx) - extraW / 2 - (isVertical ? xpad : 0))
23710
+ .attr('y', (isVertical ? vPx : uPx) - (isVertical ? lenPx : ypad + moveY - hColorbarMoveTitle))
23711
+ .attr(isVertical ? 'width' : 'height', Math.max(outerThickness - hColorbarMoveTitle, 2))
23712
+ .attr(isVertical ? 'height' : 'width', Math.max(lenPx + extraW, 2))
23713
+ .call(Color.fill, bgcolor)
23538
23714
  .call(Color.stroke, opts.bordercolor)
23539
23715
  .style('stroke-width', borderwidth);
23540
23716
 
23541
- g.selectAll('.' + cn.cboutline).attr({
23542
- x: uPx,
23543
- y: vPx - lenPx + ypad + (titleSide === 'top' ? titleHeight : 0),
23544
- width: Math.max(thickPx, 2),
23545
- height: Math.max(lenPx - 2 * ypad - titleHeight, 2)
23546
- })
23717
+ var moveX = rightSideHorizontal ? Math.max(titleWidth - 10, 0) : 0;
23718
+
23719
+ g.selectAll('.' + cn.cboutline)
23720
+ .attr('x', (isVertical ? uPx : vPx + xpad) + moveX)
23721
+ .attr('y', (isVertical ? vPx + ypad - lenPx : uPx) + (topSideVertical ? titleHeight : 0))
23722
+ .attr(isVertical ? 'width' : 'height', Math.max(thickPx, 2))
23723
+ .attr(isVertical ? 'height' : 'width', Math.max(lenPx - (isVertical ?
23724
+ 2 * ypad + titleHeight :
23725
+ 2 * xpad + moveX
23726
+ ), 2))
23547
23727
  .call(Color.stroke, opts.outlinecolor)
23548
23728
  .style({
23549
23729
  fill: 'none',
23550
23730
  'stroke-width': outlinewidth
23551
23731
  });
23552
23732
 
23553
- // fix positioning for xanchor!='left'
23554
- var xoffset = ({center: 0.5, right: 1}[xanchor] || 0) * outerThickness;
23555
- g.attr('transform', strTranslate(gs.l - xoffset, gs.t));
23733
+ g.attr('transform', strTranslate(
23734
+ gs.l - (isVertical ? xRatio * outerThickness : 0),
23735
+ gs.t - (isVertical ? 0 : (1 - yRatio) * outerThickness - moveY)
23736
+ ));
23737
+
23738
+ if(!isVertical && (
23739
+ borderwidth || (
23740
+ tinycolor(bgcolor).getAlpha() &&
23741
+ !tinycolor.equals(fullLayout.paper_bgcolor, bgcolor)
23742
+ )
23743
+ )) {
23744
+ // for horizontal colorbars when there is a border line or having different background color
23745
+ // hide/adjust x positioning for the first/last tick labels if they go outside the border
23746
+ var tickLabels = axLayer.selectAll('text');
23747
+ var numTicks = tickLabels[0].length;
23748
+
23749
+ var border = g.select('.' + cn.cbbg).node();
23750
+ var oBb = Drawing.bBox(border);
23751
+ var oTr = Drawing.getTranslate(g);
23752
+
23753
+ var TEXTPAD = 2;
23754
+
23755
+ tickLabels.each(function(d, i) {
23756
+ var first = 0;
23757
+ var last = numTicks - 1;
23758
+ if(i === first || i === last) {
23759
+ var iBb = Drawing.bBox(this);
23760
+ var iTr = Drawing.getTranslate(this);
23761
+ var deltaX;
23762
+
23763
+ if(i === last) {
23764
+ var iRight = iBb.right + iTr.x;
23765
+ var oRight = oBb.right + oTr.x + vPx - borderwidth - TEXTPAD + optsX;
23766
+
23767
+ deltaX = oRight - iRight;
23768
+ if(deltaX > 0) deltaX = 0;
23769
+ } else if(i === first) {
23770
+ var iLeft = iBb.left + iTr.x;
23771
+ var oLeft = oBb.left + oTr.x + vPx + borderwidth + TEXTPAD;
23772
+
23773
+ deltaX = oLeft - iLeft;
23774
+ if(deltaX < 0) deltaX = 0;
23775
+ }
23776
+
23777
+ if(deltaX) {
23778
+ if(numTicks < 3) { // adjust position
23779
+ this.setAttribute('transform',
23780
+ 'translate(' + deltaX + ',0) ' +
23781
+ this.getAttribute('transform')
23782
+ );
23783
+ } else { // hide
23784
+ this.setAttribute('visibility', 'hidden');
23785
+ }
23786
+ }
23787
+ }
23788
+ });
23789
+ }
23556
23790
 
23557
23791
  // auto margin adjustment
23558
23792
  var marginOpts = {};
23793
+ var lFrac = FROM_TL[xanchor];
23794
+ var rFrac = FROM_BR[xanchor];
23559
23795
  var tFrac = FROM_TL[yanchor];
23560
23796
  var bFrac = FROM_BR[yanchor];
23561
- if(lenmode === 'pixels') {
23562
- marginOpts.y = optsY;
23563
- marginOpts.t = lenPx * tFrac;
23564
- marginOpts.b = lenPx * bFrac;
23565
- } else {
23566
- marginOpts.t = marginOpts.b = 0;
23567
- marginOpts.yt = optsY + len * tFrac;
23568
- marginOpts.yb = optsY - len * bFrac;
23569
- }
23570
23797
 
23571
- var lFrac = FROM_TL[xanchor];
23572
- var rFrac = FROM_BR[xanchor];
23573
- if(thicknessmode === 'pixels') {
23574
- marginOpts.x = optsX;
23575
- marginOpts.l = outerThickness * lFrac;
23576
- marginOpts.r = outerThickness * rFrac;
23577
- } else {
23578
- var extraThickness = outerThickness - thickPx;
23579
- marginOpts.l = extraThickness * lFrac;
23580
- marginOpts.r = extraThickness * rFrac;
23581
- marginOpts.xl = optsX - thickness * lFrac;
23582
- marginOpts.xr = optsX + thickness * rFrac;
23798
+ var extraThickness = outerThickness - thickPx;
23799
+ if(isVertical) {
23800
+ if(lenmode === 'pixels') {
23801
+ marginOpts.y = optsY;
23802
+ marginOpts.t = lenPx * tFrac;
23803
+ marginOpts.b = lenPx * bFrac;
23804
+ } else {
23805
+ marginOpts.t = marginOpts.b = 0;
23806
+ marginOpts.yt = optsY + len * tFrac;
23807
+ marginOpts.yb = optsY - len * bFrac;
23808
+ }
23809
+
23810
+ if(thicknessmode === 'pixels') {
23811
+ marginOpts.x = optsX;
23812
+ marginOpts.l = outerThickness * lFrac;
23813
+ marginOpts.r = outerThickness * rFrac;
23814
+ } else {
23815
+ marginOpts.l = extraThickness * lFrac;
23816
+ marginOpts.r = extraThickness * rFrac;
23817
+ marginOpts.xl = optsX - thickness * lFrac;
23818
+ marginOpts.xr = optsX + thickness * rFrac;
23819
+ }
23820
+ } else { // horizontal colorbars
23821
+ if(lenmode === 'pixels') {
23822
+ marginOpts.x = optsX;
23823
+ marginOpts.l = lenPx * lFrac;
23824
+ marginOpts.r = lenPx * rFrac;
23825
+ } else {
23826
+ marginOpts.l = marginOpts.r = 0;
23827
+ marginOpts.xl = optsX + len * lFrac;
23828
+ marginOpts.xr = optsX - len * rFrac;
23829
+ }
23830
+
23831
+ if(thicknessmode === 'pixels') {
23832
+ marginOpts.y = 1 - optsY;
23833
+ marginOpts.t = outerThickness * tFrac;
23834
+ marginOpts.b = outerThickness * bFrac;
23835
+ } else {
23836
+ marginOpts.t = extraThickness * tFrac;
23837
+ marginOpts.b = extraThickness * bFrac;
23838
+ marginOpts.yt = optsY - thickness * tFrac;
23839
+ marginOpts.yb = optsY + thickness * bFrac;
23840
+ }
23583
23841
  }
23584
23842
 
23585
23843
  Plots.autoMargin(gd, opts._id, marginOpts);
@@ -23596,6 +23854,7 @@ function drawColorBar(g, opts, gd) {
23596
23854
  }
23597
23855
 
23598
23856
  function makeEditable(g, opts, gd) {
23857
+ var isVertical = opts.orientation === 'v';
23599
23858
  var fullLayout = gd._fullLayout;
23600
23859
  var gs = fullLayout._size;
23601
23860
  var t0, xf, yf;
@@ -23610,9 +23869,13 @@ function makeEditable(g, opts, gd) {
23610
23869
  moveFn: function(dx, dy) {
23611
23870
  g.attr('transform', t0 + strTranslate(dx, dy));
23612
23871
 
23613
- xf = dragElement.align(opts._uFrac + (dx / gs.w), opts._thickFrac,
23872
+ xf = dragElement.align(
23873
+ (isVertical ? opts._uFrac : opts._vFrac) + (dx / gs.w),
23874
+ isVertical ? opts._thickFrac : opts._lenFrac,
23614
23875
  0, 1, opts.xanchor);
23615
- yf = dragElement.align(opts._vFrac - (dy / gs.h), opts._lenFrac,
23876
+ yf = dragElement.align(
23877
+ (isVertical ? opts._vFrac : (1 - opts._uFrac)) - (dy / gs.h),
23878
+ isVertical ? opts._lenFrac : opts._thickFrac,
23616
23879
  0, 1, opts.yanchor);
23617
23880
 
23618
23881
  var csr = dragElement.getCursor(xf, yf, opts.xanchor, opts.yanchor);
@@ -23689,6 +23952,8 @@ function calcLevels(gd, opts, zrange) {
23689
23952
  function mockColorBarAxis(gd, opts, zrange) {
23690
23953
  var fullLayout = gd._fullLayout;
23691
23954
 
23955
+ var isVertical = opts.orientation === 'v';
23956
+
23692
23957
  var cbAxisIn = {
23693
23958
  type: 'linear',
23694
23959
  range: zrange,
@@ -23719,17 +23984,19 @@ function mockColorBarAxis(gd, opts, zrange) {
23719
23984
  title: opts.title,
23720
23985
  showline: true,
23721
23986
  anchor: 'free',
23722
- side: 'right',
23987
+ side: isVertical ? 'right' : 'bottom',
23723
23988
  position: 1
23724
23989
  };
23725
23990
 
23991
+ var letter = isVertical ? 'y' : 'x';
23992
+
23726
23993
  var cbAxisOut = {
23727
23994
  type: 'linear',
23728
- _id: 'y' + opts._id
23995
+ _id: letter + opts._id
23729
23996
  };
23730
23997
 
23731
23998
  var axisOptions = {
23732
- letter: 'y',
23999
+ letter: letter,
23733
24000
  font: fullLayout.font,
23734
24001
  noHover: true,
23735
24002
  noTickson: true,
@@ -26191,7 +26458,7 @@ var TEXTOFFSETSIGN = {
26191
26458
  start: 1, end: -1, middle: 0, bottom: 1, top: -1
26192
26459
  };
26193
26460
 
26194
- function textPointPosition(s, textPosition, fontSize, markerRadius) {
26461
+ function textPointPosition(s, textPosition, fontSize, markerRadius, dontTouchParent) {
26195
26462
  var group = d3.select(s.node().parentNode);
26196
26463
 
26197
26464
  var v = textPosition.indexOf('top') !== -1 ?
@@ -26213,7 +26480,9 @@ function textPointPosition(s, textPosition, fontSize, markerRadius) {
26213
26480
 
26214
26481
  // fix the overall text group position
26215
26482
  s.attr('text-anchor', h);
26216
- group.attr('transform', strTranslate(dx, dy));
26483
+ if(!dontTouchParent) {
26484
+ group.attr('transform', strTranslate(dx, dy));
26485
+ }
26217
26486
  }
26218
26487
 
26219
26488
  function extracTextFontSize(d, trace) {
@@ -26283,7 +26552,8 @@ drawing.selectedTextStyle = function(s, trace) {
26283
26552
  var fontSize = extracTextFontSize(d, trace);
26284
26553
 
26285
26554
  Color.fill(tx, tc);
26286
- textPointPosition(tx, tp, fontSize, d.mrc2 || d.mrc);
26555
+ var dontTouchParent = Registry.traceIs(trace, 'bar-like');
26556
+ textPointPosition(tx, tp, fontSize, d.mrc2 || d.mrc, dontTouchParent);
26287
26557
  });
26288
26558
  };
26289
26559
 
@@ -29339,7 +29609,9 @@ function createHoverText(hoverData, opts) {
29339
29609
  orientation: 'v'
29340
29610
  }
29341
29611
  };
29342
- var mockLayoutOut = {};
29612
+ var mockLayoutOut = {
29613
+ font: font
29614
+ };
29343
29615
  legendSupplyDefaults(mockLayoutIn, mockLayoutOut, gd._fullData);
29344
29616
  var mockLegend = mockLayoutOut.legend;
29345
29617
 
@@ -29380,7 +29652,8 @@ function createHoverText(hoverData, opts) {
29380
29652
 
29381
29653
  // Draw unified hover label
29382
29654
  mockLegend._inHover = true;
29383
- mockLegend._groupTitleFont = font;
29655
+ mockLegend._groupTitleFont = hoverlabel.grouptitlefont;
29656
+
29384
29657
  legendDraw(gd, mockLegend);
29385
29658
 
29386
29659
  // Position the hover
@@ -30382,9 +30655,11 @@ var isUnifiedHover = _dereq_('./helpers').isUnifiedHover;
30382
30655
  module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts) {
30383
30656
  opts = opts || {};
30384
30657
 
30658
+ var hasLegend = contOut.legend;
30659
+
30385
30660
  function inheritFontAttr(attr) {
30386
30661
  if(!opts.font[attr]) {
30387
- opts.font[attr] = contOut.legend ? contOut.legend.font[attr] : contOut.font[attr];
30662
+ opts.font[attr] = hasLegend ? contOut.legend.font[attr] : contOut.font[attr];
30388
30663
  }
30389
30664
  }
30390
30665
 
@@ -30395,7 +30670,7 @@ module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts
30395
30670
  inheritFontAttr('family');
30396
30671
  inheritFontAttr('color');
30397
30672
 
30398
- if(contOut.legend) {
30673
+ if(hasLegend) {
30399
30674
  if(!opts.bgcolor) opts.bgcolor = Color.combine(contOut.legend.bgcolor, contOut.paper_bgcolor);
30400
30675
  if(!opts.bordercolor) opts.bordercolor = contOut.legend.bordercolor;
30401
30676
  } else {
@@ -30504,11 +30779,13 @@ function castHoverinfo(trace, fullLayout, ptNumber) {
30504
30779
 
30505
30780
  var constants = _dereq_('./constants');
30506
30781
 
30507
- var fontAttrs = _dereq_('../../plots/font_attributes')({
30782
+ var fontAttrs = _dereq_('../../plots/font_attributes');
30783
+
30784
+ var font = fontAttrs({
30508
30785
  editType: 'none',
30509
30786
  });
30510
- fontAttrs.family.dflt = constants.HOVERFONT;
30511
- fontAttrs.size.dflt = constants.HOVERFONTSIZE;
30787
+ font.family.dflt = constants.HOVERFONT;
30788
+ font.size.dflt = constants.HOVERFONTSIZE;
30512
30789
 
30513
30790
  module.exports = {
30514
30791
  clickmode: {
@@ -30564,7 +30841,10 @@ module.exports = {
30564
30841
  valType: 'color',
30565
30842
  editType: 'none',
30566
30843
  },
30567
- font: fontAttrs,
30844
+ font: font,
30845
+ grouptitlefont: fontAttrs({
30846
+ editType: 'none',
30847
+ }),
30568
30848
  align: {
30569
30849
  valType: 'enumerated',
30570
30850
  values: ['left', 'right', 'auto'],
@@ -30577,6 +30857,7 @@ module.exports = {
30577
30857
  dflt: 15,
30578
30858
  editType: 'none',
30579
30859
  },
30860
+
30580
30861
  editType: 'none'
30581
30862
  },
30582
30863
  selectdirection: {
@@ -30624,6 +30905,8 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut) {
30624
30905
  }
30625
30906
 
30626
30907
  handleHoverLabelDefaults(layoutIn, layoutOut, coerce);
30908
+
30909
+ Lib.coerceFont(coerce, 'hoverlabel.grouptitlefont', layoutOut.hoverlabel.font);
30627
30910
  };
30628
30911
 
30629
30912
  },{"../../lib":242,"./hoverlabel_defaults":149,"./hovermode_defaults":150,"./layout_attributes":152}],154:[function(_dereq_,module,exports){
@@ -31507,6 +31790,9 @@ module.exports = {
31507
31790
  font: fontAttrs({
31508
31791
  editType: 'legend',
31509
31792
  }),
31793
+ grouptitlefont: fontAttrs({
31794
+ editType: 'legend',
31795
+ }),
31510
31796
  orientation: {
31511
31797
  valType: 'enumerated',
31512
31798
  values: ['v', 'h'],
@@ -31630,6 +31916,7 @@ var Registry = _dereq_('../../registry');
31630
31916
  var Lib = _dereq_('../../lib');
31631
31917
  var Template = _dereq_('../../plot_api/plot_template');
31632
31918
 
31919
+ var plotsAttrs = _dereq_('../../plots/attributes');
31633
31920
  var attributes = _dereq_('./attributes');
31634
31921
  var basePlotLayoutAttributes = _dereq_('../../plots/layout_attributes');
31635
31922
  var helpers = _dereq_('./helpers');
@@ -31637,13 +31924,30 @@ var helpers = _dereq_('./helpers');
31637
31924
 
31638
31925
  module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
31639
31926
  var containerIn = layoutIn.legend || {};
31927
+ var containerOut = Template.newContainer(layoutOut, 'legend');
31928
+
31929
+ function coerce(attr, dflt) {
31930
+ return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
31931
+ }
31932
+
31933
+ var trace;
31934
+ var traceCoerce = function(attr, dflt) {
31935
+ var traceIn = trace._input;
31936
+ var traceOut = trace;
31937
+ return Lib.coerce(traceIn, traceOut, plotsAttrs, attr, dflt);
31938
+ };
31939
+
31940
+ var globalFont = layoutOut.font || {};
31941
+ var grouptitlefont = Lib.coerceFont(coerce, 'grouptitlefont', Lib.extendFlat({}, globalFont, {
31942
+ size: Math.round(globalFont.size * 1.1)
31943
+ }));
31640
31944
 
31641
31945
  var legendTraceCount = 0;
31642
31946
  var legendReallyHasATrace = false;
31643
31947
  var defaultOrder = 'normal';
31644
31948
 
31645
31949
  for(var i = 0; i < fullData.length; i++) {
31646
- var trace = fullData[i];
31950
+ trace = fullData[i];
31647
31951
 
31648
31952
  if(!trace.visible) continue;
31649
31953
 
@@ -31670,6 +31974,8 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
31670
31974
  legendTraceCount++;
31671
31975
  }
31672
31976
  }
31977
+
31978
+ Lib.coerceFont(traceCoerce, 'legendgrouptitle.font', grouptitlefont);
31673
31979
  }
31674
31980
 
31675
31981
  if((Registry.traceIs(trace, 'bar') && layoutOut.barmode === 'stack') ||
@@ -31688,13 +31994,10 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
31688
31994
  basePlotLayoutAttributes, 'showlegend',
31689
31995
  legendReallyHasATrace && legendTraceCount > 1);
31690
31996
 
31691
- if(showLegend === false && !containerIn.uirevision) return;
31997
+ // delete legend
31998
+ if(showLegend === false) layoutOut.legend = undefined;
31692
31999
 
31693
- var containerOut = Template.newContainer(layoutOut, 'legend');
31694
-
31695
- function coerce(attr, dflt) {
31696
- return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
31697
- }
32000
+ if(showLegend === false && !containerIn.uirevision) return;
31698
32001
 
31699
32002
  coerce('uirevision', layoutOut.uirevision);
31700
32003
 
@@ -31756,7 +32059,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
31756
32059
  }
31757
32060
  };
31758
32061
 
31759
- },{"../../lib":242,"../../plot_api/plot_template":278,"../../plots/layout_attributes":324,"../../registry":328,"./attributes":161,"./helpers":167}],164:[function(_dereq_,module,exports){
32062
+ },{"../../lib":242,"../../plot_api/plot_template":278,"../../plots/attributes":285,"../../plots/layout_attributes":324,"../../registry":328,"./attributes":161,"./helpers":167}],164:[function(_dereq_,module,exports){
31760
32063
  'use strict';
31761
32064
 
31762
32065
  var d3 = _dereq_('@plotly/d3');
@@ -40208,8 +40511,10 @@ function draw(gd, titleClass, options) {
40208
40511
 
40209
40512
  var elShouldExist = txt || editable;
40210
40513
 
40514
+ var hColorbarMoveTitle;
40211
40515
  if(!group) {
40212
40516
  group = Lib.ensureSingle(fullLayout._infolayer, 'g', 'g-' + titleClass);
40517
+ hColorbarMoveTitle = fullLayout._hColorbarMoveTitle;
40213
40518
  }
40214
40519
 
40215
40520
  var el = group.selectAll('text')
@@ -40233,13 +40538,17 @@ function draw(gd, titleClass, options) {
40233
40538
  function drawTitle(titleEl) {
40234
40539
  var transformVal;
40235
40540
 
40541
+ if(!transform && hColorbarMoveTitle) {
40542
+ transform = {};
40543
+ }
40544
+
40236
40545
  if(transform) {
40237
40546
  transformVal = '';
40238
40547
  if(transform.rotate) {
40239
40548
  transformVal += 'rotate(' + [transform.rotate, attributes.x, attributes.y] + ')';
40240
40549
  }
40241
- if(transform.offset) {
40242
- transformVal += strTranslate(0, transform.offset);
40550
+ if(transform.offset || hColorbarMoveTitle) {
40551
+ transformVal += strTranslate(0, (transform.offset || 0) - (hColorbarMoveTitle || 0));
40243
40552
  }
40244
40553
  } else {
40245
40554
  transformVal = null;
@@ -51711,7 +52020,7 @@ function cleanDeprecatedAttributeKeys(aobj) {
51711
52020
  if((key === 'title' || oldAxisTitleRegex.test(key) || colorbarRegex.test(key)) &&
51712
52021
  (typeof value === 'string' || typeof value === 'number')) {
51713
52022
  replace(key, key.replace('title', 'title.text'));
51714
- } else if(key.indexOf('titlefont') > -1) {
52023
+ } else if(key.indexOf('titlefont') > -1 && key.indexOf('grouptitlefont') === -1) {
51715
52024
  replace(key, key.replace('titlefont', 'title.font'));
51716
52025
  } else if(key.indexOf('titleposition') > -1) {
51717
52026
  replace(key, key.replace('titleposition', 'title.position'));
@@ -52388,7 +52697,8 @@ function findUIPattern(key, patternSpecs) {
52388
52697
  var spec = patternSpecs[i];
52389
52698
  var match = key.match(spec.pattern);
52390
52699
  if(match) {
52391
- return {head: match[1], attr: spec.attr};
52700
+ var head = match[1] || '';
52701
+ return {head: head, tail: key.substr(head.length + 1), attr: spec.attr};
52392
52702
  }
52393
52703
  }
52394
52704
  }
@@ -52440,26 +52750,54 @@ function valsMatch(v1, v2) {
52440
52750
 
52441
52751
  function applyUIRevisions(data, layout, oldFullData, oldFullLayout) {
52442
52752
  var layoutPreGUI = oldFullLayout._preGUI;
52443
- var key, revAttr, oldRev, newRev, match, preGUIVal, newNP, newVal;
52753
+ var key, revAttr, oldRev, newRev, match, preGUIVal, newNP, newVal, head, tail;
52444
52754
  var bothInheritAutorange = [];
52755
+ var newAutorangeIn = {};
52445
52756
  var newRangeAccepted = {};
52446
52757
  for(key in layoutPreGUI) {
52447
52758
  match = findUIPattern(key, layoutUIControlPatterns);
52448
52759
  if(match) {
52449
- revAttr = match.attr || (match.head + '.uirevision');
52760
+ head = match.head;
52761
+ tail = match.tail;
52762
+ revAttr = match.attr || (head + '.uirevision');
52450
52763
  oldRev = nestedProperty(oldFullLayout, revAttr).get();
52451
52764
  newRev = oldRev && getNewRev(revAttr, layout);
52765
+
52452
52766
  if(newRev && (newRev === oldRev)) {
52453
52767
  preGUIVal = layoutPreGUI[key];
52454
52768
  if(preGUIVal === null) preGUIVal = undefined;
52455
52769
  newNP = nestedProperty(layout, key);
52456
52770
  newVal = newNP.get();
52771
+
52457
52772
  if(valsMatch(newVal, preGUIVal)) {
52458
- if(newVal === undefined && key.substr(key.length - 9) === 'autorange') {
52459
- bothInheritAutorange.push(key.substr(0, key.length - 10));
52773
+ if(newVal === undefined && tail === 'autorange') {
52774
+ bothInheritAutorange.push(head);
52460
52775
  }
52461
52776
  newNP.set(undefinedToNull(nestedProperty(oldFullLayout, key).get()));
52462
52777
  continue;
52778
+ } else if(tail === 'autorange' || tail.substr(0, 6) === 'range[') {
52779
+ // Special case for (auto)range since we push it back into the layout
52780
+ // so all null should be treated equivalently to autorange: true with any range
52781
+ var pre0 = layoutPreGUI[head + '.range[0]'];
52782
+ var pre1 = layoutPreGUI[head + '.range[1]'];
52783
+ var preAuto = layoutPreGUI[head + '.autorange'];
52784
+ if(preAuto || (preAuto === null && pre0 === null && pre1 === null)) {
52785
+ // Only read the input layout once and stash the result,
52786
+ // so we get it before we start modifying it
52787
+ if(!(head in newAutorangeIn)) {
52788
+ var newContainer = nestedProperty(layout, head).get();
52789
+ newAutorangeIn[head] = newContainer && (
52790
+ newContainer.autorange ||
52791
+ (newContainer.autorange !== false && (
52792
+ !newContainer.range || newContainer.range.length !== 2)
52793
+ )
52794
+ );
52795
+ }
52796
+ if(newAutorangeIn[head]) {
52797
+ newNP.set(undefinedToNull(nestedProperty(oldFullLayout, key).get()));
52798
+ continue;
52799
+ }
52800
+ }
52463
52801
  }
52464
52802
  }
52465
52803
  } else {
@@ -52470,12 +52808,12 @@ function applyUIRevisions(data, layout, oldFullData, oldFullLayout) {
52470
52808
  // so remove it from _preGUI for next time.
52471
52809
  delete layoutPreGUI[key];
52472
52810
 
52473
- if(key.substr(key.length - 8, 6) === 'range[') {
52474
- newRangeAccepted[key.substr(0, key.length - 9)] = 1;
52811
+ if(match && match.tail.substr(0, 6) === 'range[') {
52812
+ newRangeAccepted[match.head] = 1;
52475
52813
  }
52476
52814
  }
52477
52815
 
52478
- // Special logic for `autorange`, since it interacts with `range`:
52816
+ // More special logic for `autorange`, since it interacts with `range`:
52479
52817
  // If the new figure's matching `range` was kept, and `autorange`
52480
52818
  // wasn't supplied explicitly in either the original or the new figure,
52481
52819
  // we shouldn't alter that - but we may just have done that, so fix it.
@@ -69550,6 +69888,9 @@ module.exports = function(opts) {
69550
69888
  // TODO - that's uber hacky... better solution?
69551
69889
  };
69552
69890
 
69891
+ if(opts.autoSize) attrs.size.dflt = 'auto';
69892
+ if(opts.autoColor) attrs.color.dflt = 'auto';
69893
+
69553
69894
  if(opts.arrayOk) {
69554
69895
  attrs.family.arrayOk = true;
69555
69896
  attrs.size.arrayOk = true;
@@ -69909,6 +70250,7 @@ module.exports = {
69909
70250
  valType: 'boolean',
69910
70251
  editType: 'legend',
69911
70252
  },
70253
+
69912
70254
  colorway: {
69913
70255
  valType: 'colorlist',
69914
70256
  dflt: colorAttrs.defaults,
@@ -71321,13 +71663,7 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac
71321
71663
  );
71322
71664
 
71323
71665
  coerce('legendgroup');
71324
- var titleText = coerce('legendgrouptitle.text');
71325
- if(titleText) {
71326
- Lib.coerceFont(coerce, 'legendgrouptitle.font', Lib.extendFlat({}, layout.font, {
71327
- size: Math.round(layout.font.size * 1.1) // default to larger font size
71328
- }));
71329
- }
71330
-
71666
+ coerce('legendgrouptitle.text');
71331
71667
  coerce('legendrank');
71332
71668
 
71333
71669
  traceOut._dfltShowLegend = true;
@@ -71475,16 +71811,14 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut, formatObj) {
71475
71811
 
71476
71812
  coerce('autotypenumbers');
71477
71813
 
71478
- var globalFont = Lib.coerceFont(coerce, 'font');
71479
-
71480
- coerce('title.text', layoutOut._dfltTitle.plot);
71814
+ var font = Lib.coerceFont(coerce, 'font');
71815
+ var fontSize = font.size;
71481
71816
 
71482
- Lib.coerceFont(coerce, 'title.font', {
71483
- family: globalFont.family,
71484
- size: Math.round(globalFont.size * 1.4),
71485
- color: globalFont.color
71486
- });
71817
+ Lib.coerceFont(coerce, 'title.font', Lib.extendFlat({}, font, {
71818
+ size: Math.round(fontSize * 1.4)
71819
+ }));
71487
71820
 
71821
+ coerce('title.text', layoutOut._dfltTitle.plot);
71488
71822
  coerce('title.xref');
71489
71823
  coerce('title.yref');
71490
71824
  coerce('title.x');
@@ -76821,7 +77155,7 @@ function appendBarText(gd, plotinfo, bar, cd, i, x0, x1, y0, y1, opts, makeOnCom
76821
77155
  }
76822
77156
 
76823
77157
  transform.fontSize = font.size;
76824
- recordMinTextSize(trace.type, transform, fullLayout);
77158
+ recordMinTextSize(trace.type === 'histogram' ? 'bar' : trace.type, transform, fullLayout);
76825
77159
  calcBar.transform = transform;
76826
77160
 
76827
77161
  transition(textSelection, fullLayout, opts, makeOnCompleteCallback)
@@ -80065,6 +80399,8 @@ module.exports = function style(gd) {
80065
80399
  var barAttrs = _dereq_('../bar/attributes');
80066
80400
  var axisHoverFormat = _dereq_('../../plots/cartesian/axis_format_attributes').axisHoverFormat;
80067
80401
  var hovertemplateAttrs = _dereq_('../../plots/template_attributes').hovertemplateAttrs;
80402
+ var texttemplateAttrs = _dereq_('../../plots/template_attributes').texttemplateAttrs;
80403
+ var fontAttrs = _dereq_('../../plots/font_attributes');
80068
80404
  var makeBinAttrs = _dereq_('./bin_attributes');
80069
80405
  var constants = _dereq_('./constants');
80070
80406
  var extendFlat = _dereq_('../../lib/extend').extendFlat;
@@ -80159,6 +80495,41 @@ module.exports = {
80159
80495
  keys: constants.eventDataKeys
80160
80496
  }),
80161
80497
 
80498
+ texttemplate: texttemplateAttrs({
80499
+ arrayOk: false,
80500
+ editType: 'plot'
80501
+ }, {
80502
+ keys: ['label', 'value']
80503
+ }),
80504
+
80505
+ textposition: extendFlat({}, barAttrs.textposition, {
80506
+ arrayOk: false
80507
+ }),
80508
+
80509
+ textfont: fontAttrs({
80510
+ arrayOk: false,
80511
+ editType: 'plot',
80512
+ colorEditType: 'style',
80513
+ }),
80514
+
80515
+ outsidetextfont: fontAttrs({
80516
+ arrayOk: false,
80517
+ editType: 'plot',
80518
+ colorEditType: 'style',
80519
+ }),
80520
+
80521
+ insidetextfont: fontAttrs({
80522
+ arrayOk: false,
80523
+ editType: 'plot',
80524
+ colorEditType: 'style',
80525
+ }),
80526
+
80527
+ insidetextanchor: barAttrs.insidetextanchor,
80528
+
80529
+ textangle: barAttrs.textangle,
80530
+ cliponaxis: barAttrs.cliponaxis,
80531
+ constraintext: barAttrs.constraintext,
80532
+
80162
80533
  marker: barAttrs.marker,
80163
80534
 
80164
80535
  offsetgroup: barAttrs.offsetgroup,
@@ -80172,7 +80543,7 @@ module.exports = {
80172
80543
  }
80173
80544
  };
80174
80545
 
80175
- },{"../../lib/extend":236,"../../plots/cartesian/axis_format_attributes":292,"../../plots/template_attributes":327,"../bar/attributes":338,"./bin_attributes":389,"./constants":393}],388:[function(_dereq_,module,exports){
80546
+ },{"../../lib/extend":236,"../../plots/cartesian/axis_format_attributes":292,"../../plots/font_attributes":320,"../../plots/template_attributes":327,"../bar/attributes":338,"./bin_attributes":389,"./constants":393}],388:[function(_dereq_,module,exports){
80176
80547
  'use strict';
80177
80548
 
80178
80549
 
@@ -81295,6 +81666,7 @@ var Registry = _dereq_('../../registry');
81295
81666
  var Lib = _dereq_('../../lib');
81296
81667
  var Color = _dereq_('../../components/color');
81297
81668
 
81669
+ var handleText = _dereq_('../bar/defaults').handleText;
81298
81670
  var handleStyleDefaults = _dereq_('../bar/style_defaults');
81299
81671
  var attributes = _dereq_('./attributes');
81300
81672
 
@@ -81313,6 +81685,16 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
81313
81685
  }
81314
81686
 
81315
81687
  coerce('text');
81688
+ var textposition = coerce('textposition');
81689
+ handleText(traceIn, traceOut, layout, coerce, textposition, {
81690
+ moduleHasSelected: true,
81691
+ moduleHasUnselected: true,
81692
+ moduleHasConstrain: true,
81693
+ moduleHasCliponaxis: true,
81694
+ moduleHasTextangle: true,
81695
+ moduleHasInsideanchor: true
81696
+ });
81697
+
81316
81698
  coerce('hovertext');
81317
81699
  coerce('hovertemplate');
81318
81700
  coerce('xhoverformat');
@@ -81356,7 +81738,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
81356
81738
  errorBarsSupplyDefaults(traceIn, traceOut, lineColor || Color.defaultLine, {axis: 'x', inherit: 'y'});
81357
81739
  };
81358
81740
 
81359
- },{"../../components/color":111,"../../lib":242,"../../registry":328,"../bar/style_defaults":353,"./attributes":387}],396:[function(_dereq_,module,exports){
81741
+ },{"../../components/color":111,"../../lib":242,"../../registry":328,"../bar/defaults":342,"../bar/style_defaults":353,"./attributes":387}],396:[function(_dereq_,module,exports){
81360
81742
  'use strict';
81361
81743
 
81362
81744
  module.exports = function eventData(out, pt, trace, cd, pointNumber) {
@@ -83808,7 +84190,6 @@ function calc(gd, trace) {
83808
84190
  v = vals[i];
83809
84191
  if(!isNumeric(v)) continue;
83810
84192
  v = +v;
83811
- if(v < 0) continue;
83812
84193
  } else v = 1;
83813
84194
 
83814
84195
  label = labels[i];
@@ -83845,6 +84226,9 @@ function calc(gd, trace) {
83845
84226
  }
83846
84227
  }
83847
84228
 
84229
+ // Drop aggregate sums of value 0 or less
84230
+ cd = cd.filter(function(elem) { return elem.v >= 0; });
84231
+
83848
84232
  var shouldSort = (trace.type === 'funnelarea') ? isAggregated : trace.sort;
83849
84233
  if(shouldSort) cd.sort(function(a, b) { return b.v - a.v; });
83850
84234
 
@@ -90226,7 +90610,7 @@ function getSortFunc(opts, d2c) {
90226
90610
  'use strict';
90227
90611
 
90228
90612
  // package version injected by `npm run preprocess`
90229
- exports.version = '2.6.3';
90613
+ exports.version = '2.8.1';
90230
90614
 
90231
90615
  },{}]},{},[12])(12)
90232
90616
  });