plotly.js 2.6.2 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +3 -3
  3. package/dist/README.md +26 -26
  4. package/dist/plot-schema.json +1015 -407
  5. package/dist/plotly-basic.js +568 -225
  6. package/dist/plotly-basic.min.js +4 -4
  7. package/dist/plotly-cartesian.js +1029 -371
  8. package/dist/plotly-cartesian.min.js +3 -3
  9. package/dist/plotly-finance.js +618 -227
  10. package/dist/plotly-finance.min.js +4 -4
  11. package/dist/plotly-geo-assets.js +2 -2
  12. package/dist/plotly-geo.js +564 -223
  13. package/dist/plotly-geo.min.js +2 -2
  14. package/dist/plotly-gl2d.js +580 -224
  15. package/dist/plotly-gl2d.min.js +2 -2
  16. package/dist/plotly-gl3d.js +564 -223
  17. package/dist/plotly-gl3d.min.js +2 -2
  18. package/dist/plotly-mapbox.js +570 -226
  19. package/dist/plotly-mapbox.min.js +2 -2
  20. package/dist/plotly-strict.js +1253 -592
  21. package/dist/plotly-strict.min.js +3 -3
  22. package/dist/plotly-with-meta.js +1345 -654
  23. package/dist/plotly.js +1307 -646
  24. package/dist/plotly.min.js +10 -10
  25. package/package.json +9 -9
  26. package/src/components/colorbar/attributes.js +29 -20
  27. package/src/components/colorbar/defaults.js +30 -8
  28. package/src/components/colorbar/draw.js +398 -141
  29. package/src/components/drawing/index.js +6 -3
  30. package/src/components/fx/hover.js +16 -17
  31. package/src/components/fx/hoverlabel_defaults.js +4 -2
  32. package/src/components/fx/layout_attributes.js +14 -4
  33. package/src/components/fx/layout_defaults.js +2 -0
  34. package/src/components/legend/attributes.js +7 -0
  35. package/src/components/legend/defaults.js +24 -7
  36. package/src/components/titles/index.js +8 -2
  37. package/src/plot_api/plot_api.js +38 -9
  38. package/src/plots/font_attributes.js +3 -0
  39. package/src/plots/layout_attributes.js +1 -0
  40. package/src/plots/mapbox/mapbox.js +6 -3
  41. package/src/plots/plots.js +7 -15
  42. package/src/traces/bar/plot.js +1 -1
  43. package/src/traces/contour/attributes.js +12 -0
  44. package/src/traces/contour/defaults.js +9 -1
  45. package/src/traces/heatmap/attributes.js +16 -0
  46. package/src/traces/heatmap/defaults.js +2 -0
  47. package/src/traces/heatmap/label_defaults.js +13 -0
  48. package/src/traces/heatmap/plot.js +203 -4
  49. package/src/traces/histogram/attributes.js +40 -0
  50. package/src/traces/histogram/defaults.js +11 -0
  51. package/src/traces/histogram2d/attributes.js +8 -0
  52. package/src/traces/histogram2d/defaults.js +4 -0
  53. package/src/traces/histogram2dcontour/attributes.js +3 -1
  54. package/src/traces/histogram2dcontour/defaults.js +8 -1
  55. package/src/traces/pie/calc.js +3 -1
  56. package/src/version.js +1 -1
  57. package/tasks/test_mock.js +1 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * plotly.js (finance) v2.6.2
2
+ * plotly.js (finance) v2.8.0
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,6 +23204,21 @@ function makeColorBarData(gd) {
23183
23204
  }
23184
23205
 
23185
23206
  function drawColorBar(g, opts, gd) {
23207
+ var isVertical = opts.orientation === 'v';
23208
+ var len = opts.len;
23209
+ var lenmode = opts.lenmode;
23210
+ var thickness = opts.thickness;
23211
+ var thicknessmode = opts.thicknessmode;
23212
+ var outlinewidth = opts.outlinewidth;
23213
+ var borderwidth = opts.borderwidth;
23214
+ var bgcolor = opts.bgcolor;
23215
+ var xanchor = opts.xanchor;
23216
+ var yanchor = opts.yanchor;
23217
+ var xpad = opts.xpad;
23218
+ var ypad = opts.ypad;
23219
+ var optsX = opts.x;
23220
+ var optsY = isVertical ? opts.y : 1 - opts.y;
23221
+
23186
23222
  var fullLayout = gd._fullLayout;
23187
23223
  var gs = fullLayout._size;
23188
23224
 
@@ -23212,42 +23248,64 @@ function drawColorBar(g, opts, gd) {
23212
23248
  // when the colorbar itself is pushing the margins.
23213
23249
  // but then the fractional size is calculated based on the
23214
23250
  // actual graph size, so that the axes will size correctly.
23215
- var thickPx = Math.round(opts.thickness * (opts.thicknessmode === 'fraction' ? gs.w : 1));
23216
- var thickFrac = thickPx / gs.w;
23217
- var lenPx = Math.round(opts.len * (opts.lenmode === 'fraction' ? gs.h : 1));
23218
- var lenFrac = lenPx / gs.h;
23219
- var xpadFrac = opts.xpad / gs.w;
23220
- var yExtraPx = (opts.borderwidth + opts.outlinewidth) / 2;
23221
- var ypadFrac = opts.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);
23222
23255
 
23223
23256
  // x positioning: do it initially just for left anchor,
23224
23257
  // then fix at the end (since we don't know the width yet)
23225
- var xLeft = Math.round(opts.x * gs.w + opts.xpad);
23226
- // for dragging... this is getting a little muddled...
23227
- var xLeftFrac = opts.x - thickFrac * ({center: 0.5, right: 1}[opts.xanchor] || 0);
23258
+ var uPx = Math.round(isVertical ?
23259
+ optsX * gs.w + xpad :
23260
+ optsY * gs.h + ypad
23261
+ );
23228
23262
 
23229
- // y positioning we can do correctly from the start
23230
- var yBottomFrac = opts.y + lenFrac * (({top: -0.5, bottom: 0.5}[opts.yanchor] || 0) - 0.5);
23231
- var yBottomPx = Math.round(gs.h * (1 - yBottomFrac));
23232
- var yTopPx = yBottomPx - lenPx;
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
+ );
23233
23280
 
23234
23281
  // stash a few things for makeEditable
23235
23282
  opts._lenFrac = lenFrac;
23236
23283
  opts._thickFrac = thickFrac;
23237
- opts._xLeftFrac = xLeftFrac;
23238
- opts._yBottomFrac = yBottomFrac;
23284
+ opts._uFrac = uFrac;
23285
+ opts._vFrac = vFrac;
23239
23286
 
23240
23287
  // stash mocked axis for contour label formatting
23241
23288
  var ax = opts._axis = mockColorBarAxis(gd, opts, zrange);
23242
23289
 
23243
23290
  // position can't go in through supplyDefaults
23244
23291
  // because that restricts it to [0,1]
23245
- ax.position = opts.x + 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
+ }
23246
23304
 
23247
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
23305
+ if(!isVertical && !topOrBottom) {
23248
23306
  ax.title.side = titleSide;
23249
- ax.titlex = opts.x + xpadFrac;
23250
- ax.titley = yBottomFrac + (title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
23307
+ ax.titley = optsY + ypad / gs.h;
23308
+ ax.titlex = vFrac + xpad / gs.w; // right side
23251
23309
  }
23252
23310
 
23253
23311
  if(line.color && opts.tickmode === 'auto') {
@@ -23255,7 +23313,7 @@ function drawColorBar(g, opts, gd) {
23255
23313
  ax.tick0 = levelsIn.start;
23256
23314
  var dtick = levelsIn.size;
23257
23315
  // expand if too many contours, so we don't get too many ticks
23258
- var autoNtick = Lib.constrain((yBottomPx - yTopPx) / 50, 4, 15) + 1;
23316
+ var autoNtick = Lib.constrain(lenPx / 50, 4, 15) + 1;
23259
23317
  var dtFactor = (zrange[1] - zrange[0]) / ((opts.nticks || autoNtick) * dtick);
23260
23318
  if(dtFactor > 1) {
23261
23319
  var dtexp = Math.pow(10, Math.floor(Math.log(dtFactor) / Math.LN10));
@@ -23272,9 +23330,12 @@ function drawColorBar(g, opts, gd) {
23272
23330
 
23273
23331
  // set domain after init, because we may want to
23274
23332
  // allow it outside [0,1]
23275
- ax.domain = [
23276
- yBottomFrac + ypadFrac,
23277
- yBottomFrac + 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
23278
23339
  ];
23279
23340
 
23280
23341
  ax.setScale();
@@ -23284,9 +23345,13 @@ function drawColorBar(g, opts, gd) {
23284
23345
  var titleCont = g.select('.' + cn.cbtitleunshift)
23285
23346
  .attr('transform', strTranslate(-Math.round(gs.l), -Math.round(gs.t)));
23286
23347
 
23348
+ var ticklabelposition = ax.ticklabelposition;
23349
+ var titleFontSize = ax.title.font.size;
23350
+
23287
23351
  var axLayer = g.select('.' + cn.cbaxis);
23288
23352
  var titleEl;
23289
23353
  var titleHeight = 0;
23354
+ var titleWidth = 0;
23290
23355
 
23291
23356
  function drawTitle(titleClass, titleOpts) {
23292
23357
  var dfltTitleOpts = {
@@ -23311,58 +23376,102 @@ function drawColorBar(g, opts, gd) {
23311
23376
  }
23312
23377
 
23313
23378
  function drawDummyTitle() {
23314
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
23315
- // draw the title so we know how much room it needs
23316
- // when we squish the axis. This one only applies to
23317
- // top or bottom titles, not right side.
23318
- var x = gs.l + (opts.x + xpadFrac) * gs.w;
23319
- var fontSize = ax.title.font.size;
23320
- 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;
23321
23389
 
23322
23390
  if(titleSide === 'top') {
23323
- y = (1 - (yBottomFrac + lenFrac - ypadFrac)) * gs.h +
23324
- gs.t + 3 + fontSize * 0.75;
23325
- } else {
23326
- y = (1 - (yBottomFrac + ypadFrac)) * gs.h +
23327
- 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;
23328
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;
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
+
23329
23405
  drawTitle(ax._id + 'title', {
23330
- attributes: {x: x, y: y, 'text-anchor': 'start'}
23406
+ attributes: {x: x, y: y, 'text-anchor': isVertical ? 'start' : 'middle'}
23331
23407
  });
23332
23408
  }
23333
23409
  }
23334
23410
 
23335
23411
  function drawCbTitle() {
23336
- if(['top', 'bottom'].indexOf(titleSide) === -1) {
23337
- var fontSize = ax.title.font.size;
23338
- var y = ax._offset + ax._length / 2;
23339
- var x = gs.l + (ax.position || 0) * gs.w + ((ax.side === 'right') ?
23340
- 10 + fontSize * ((ax.showticklabels ? 1 : 0.5)) :
23341
- -10 - fontSize * ((ax.showticklabels ? 0.5 : 0)));
23342
-
23343
- // the 'h' + is a hack to get around the fact that
23344
- // convertToTspans rotates any 'y...' class by 90 degrees.
23345
- // TODO: find a better way to control this.
23346
- 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', {
23347
23453
  avoid: {
23348
23454
  selection: d3.select(gd).selectAll('g.' + ax._id + 'tick'),
23349
23455
  side: titleSide,
23350
- offsetLeft: gs.l,
23351
- offsetTop: 0,
23352
- maxShift: fullLayout.width
23456
+ offsetTop: isVertical ? 0 : gs.t,
23457
+ offsetLeft: isVertical ? gs.l : 0,
23458
+ maxShift: isVertical ? fullLayout.width : fullLayout.height
23353
23459
  },
23354
23460
  attributes: {x: x, y: y, 'text-anchor': 'middle'},
23355
- transform: {rotate: '-90', offset: 0}
23461
+ transform: {rotate: isVertical ? -90 : 0, offset: 0}
23356
23462
  });
23357
23463
  }
23358
23464
  }
23359
23465
 
23360
23466
  function drawAxis() {
23361
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
23467
+ if(
23468
+ (!isVertical && !topOrBottom) ||
23469
+ (isVertical && topOrBottom)
23470
+ ) {
23362
23471
  // squish the axis top to make room for the title
23363
23472
  var titleGroup = g.select('.' + cn.cbtitle);
23364
23473
  var titleText = titleGroup.select('text');
23365
- var titleTrans = [-opts.outlinewidth / 2, opts.outlinewidth / 2];
23474
+ var titleTrans = [-outlinewidth / 2, outlinewidth / 2];
23366
23475
  var mathJaxNode = titleGroup
23367
23476
  .select('.h' + ax._id + 'title-math-group')
23368
23477
  .node();
@@ -23370,39 +23479,63 @@ function drawColorBar(g, opts, gd) {
23370
23479
  if(titleText.node()) {
23371
23480
  lineSize = parseInt(titleText.node().style.fontSize, 10) * LINE_SPACING;
23372
23481
  }
23482
+
23483
+ var bb;
23373
23484
  if(mathJaxNode) {
23374
- titleHeight = Drawing.bBox(mathJaxNode).height;
23485
+ bb = Drawing.bBox(mathJaxNode);
23486
+ titleWidth = bb.width;
23487
+ titleHeight = bb.height;
23375
23488
  if(titleHeight > lineSize) {
23376
23489
  // not entirely sure how mathjax is doing
23377
23490
  // vertical alignment, but this seems to work.
23378
23491
  titleTrans[1] -= (titleHeight - lineSize) / 2;
23379
23492
  }
23380
23493
  } else if(titleText.node() && !titleText.classed(cn.jsPlaceholder)) {
23381
- titleHeight = Drawing.bBox(titleText.node()).height;
23494
+ bb = Drawing.bBox(titleText.node());
23495
+ titleWidth = bb.width;
23496
+ titleHeight = bb.height;
23382
23497
  }
23383
- if(titleHeight) {
23384
- // buffer btwn colorbar and title
23385
- // TODO: configurable
23386
- titleHeight += 5;
23387
23498
 
23388
- if(titleSide === 'top') {
23389
- ax.domain[1] -= titleHeight / gs.h;
23390
- titleTrans[1] *= -1;
23391
- } else {
23392
- ax.domain[0] += titleHeight / gs.h;
23393
- var nlines = svgTextUtils.lineCount(titleText);
23394
- 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();
23395
23516
  }
23517
+ } else { // horizontal colorbars
23518
+ if(titleWidth) {
23519
+ if(titleSide === 'right') {
23520
+ ax.domain[0] += (titleWidth + titleFontSize / 2) / gs.w;
23521
+ }
23396
23522
 
23397
- titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
23398
- ax.setScale();
23523
+ titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
23524
+ ax.setScale();
23525
+ }
23399
23526
  }
23400
23527
  }
23401
23528
 
23402
23529
  g.selectAll('.' + cn.cbfills + ',.' + cn.cblines)
23403
- .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
+ );
23404
23534
 
23405
- 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
+ );
23406
23539
 
23407
23540
  var fills = g.select('.' + cn.cbfills)
23408
23541
  .selectAll('rect.' + cn.cbfill)
@@ -23428,20 +23561,22 @@ function drawColorBar(g, opts, gd) {
23428
23561
 
23429
23562
  // offset the side adjoining the next rectangle so they
23430
23563
  // overlap, to prevent antialiasing gaps
23431
- z[1] = Lib.constrain(z[1] + (z[1] > z[0]) ? 1 : -1, zBounds[0], zBounds[1]);
23432
-
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
+ } */
23433
23569
 
23434
23570
  // Colorbar cannot currently support opacities so we
23435
23571
  // use an opaque fill even when alpha channels present
23436
- var fillEl = d3.select(this).attr({
23437
- x: xLeft,
23438
- width: Math.max(thickPx, 2),
23439
- y: d3.min(z),
23440
- height: Math.max(d3.max(z) - d3.min(z), 2),
23441
- });
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));
23442
23577
 
23443
23578
  if(opts._fillgradient) {
23444
- Drawing.gradient(fillEl, gd, opts._id, 'vertical', opts._fillgradient, 'fill');
23579
+ Drawing.gradient(fillEl, gd, opts._id, isVertical ? 'vertical' : 'horizontalreversed', opts._fillgradient, 'fill');
23445
23580
  } else {
23446
23581
  // tinycolor can't handle exponents and
23447
23582
  // at this scale, removing it makes no difference.
@@ -23457,17 +23592,23 @@ function drawColorBar(g, opts, gd) {
23457
23592
  .classed(cn.cbline, true);
23458
23593
  lines.exit().remove();
23459
23594
  lines.each(function(d) {
23595
+ var a = uPx;
23596
+ var b = (Math.round(ax.c2p(d)) + (line.width / 2) % 1);
23597
+
23460
23598
  d3.select(this)
23461
- .attr('d', 'M' + xLeft + ',' +
23462
- (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
+ )
23463
23604
  .call(Drawing.lineGroupStyle, line.width, lineColormap(d), line.dash);
23464
23605
  });
23465
23606
 
23466
23607
  // force full redraw of labels and ticks
23467
23608
  axLayer.selectAll('g.' + ax._id + 'tick,path').remove();
23468
23609
 
23469
- var shift = xLeft + thickPx +
23470
- (opts.outlinewidth || 0) / 2 - (opts.ticks === 'outside' ? 1 : 0);
23610
+ var shift = uPx + thickPx +
23611
+ (outlinewidth || 0) / 2 - (opts.ticks === 'outside' ? 1 : 0);
23471
23612
 
23472
23613
  var vals = Axes.calcTicks(ax);
23473
23614
  var tickSign = Axes.getTickSigns(ax)[2];
@@ -23492,83 +23633,211 @@ function drawColorBar(g, opts, gd) {
23492
23633
  // TODO: why are we redrawing multiple times now with this?
23493
23634
  // I guess autoMargin doesn't like being post-promise?
23494
23635
  function positionCB() {
23495
- var innerWidth = thickPx + opts.outlinewidth / 2;
23496
- if(ax.ticklabelposition.indexOf('inside') === -1) {
23497
- innerWidth += Drawing.bBox(axLayer.node()).width;
23636
+ var bb;
23637
+ var innerThickness = thickPx + outlinewidth / 2;
23638
+ if(ticklabelposition.indexOf('inside') === -1) {
23639
+ bb = Drawing.bBox(axLayer.node());
23640
+ innerThickness += isVertical ? bb.width : bb.height;
23498
23641
  }
23499
23642
 
23500
23643
  titleEl = titleCont.select('text');
23501
23644
 
23645
+ var titleWidth = 0;
23646
+
23647
+ var topSideVertical = isVertical && titleSide === 'top';
23648
+ var rightSideHorizontal = !isVertical && titleSide === 'right';
23649
+
23650
+ var moveY = 0;
23651
+
23502
23652
  if(titleEl.node() && !titleEl.classed(cn.jsPlaceholder)) {
23653
+ var _titleHeight;
23654
+
23503
23655
  var mathJaxNode = titleCont.select('.h' + ax._id + 'title-math-group').node();
23504
- var titleWidth;
23505
- if(mathJaxNode && ['top', 'bottom'].indexOf(titleSide) !== -1) {
23506
- 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;
23507
23663
  } else {
23508
23664
  // note: the formula below works for all title sides,
23509
23665
  // (except for top/bottom mathjax, above)
23510
23666
  // but the weird gs.l is because the titleunshift
23511
23667
  // transform gets removed by Drawing.bBox
23512
- titleWidth = Drawing.bBox(titleCont.node()).right - xLeft - 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
+ }
23678
+ }
23679
+
23680
+ if(rightSideHorizontal) {
23681
+ titleEl.attr('transform', strTranslate(titleWidth / 2 + titleFontSize / 2, 0));
23682
+
23683
+ titleWidth *= 2;
23513
23684
  }
23514
- innerWidth = Math.max(innerWidth, titleWidth);
23685
+
23686
+ innerThickness = Math.max(innerThickness,
23687
+ isVertical ? titleWidth : _titleHeight
23688
+ );
23515
23689
  }
23516
23690
 
23517
- var outerwidth = 2 * opts.xpad + innerWidth + opts.borderwidth + opts.outlinewidth / 2;
23518
- var outerheight = yBottomPx - yTopPx;
23691
+ var outerThickness = (isVertical ?
23692
+ xpad :
23693
+ ypad
23694
+ ) * 2 + innerThickness + borderwidth + outlinewidth / 2;
23519
23695
 
23520
- g.select('.' + cn.cbbg).attr({
23521
- x: xLeft - opts.xpad - (opts.borderwidth + opts.outlinewidth) / 2,
23522
- y: yTopPx - yExtraPx,
23523
- width: Math.max(outerwidth, 2),
23524
- height: Math.max(outerheight + 2 * yExtraPx, 2)
23525
- })
23526
- .call(Color.fill, opts.bgcolor)
23527
- .call(Color.stroke, opts.bordercolor)
23528
- .style('stroke-width', opts.borderwidth);
23696
+ var hColorbarMoveTitle = 0;
23697
+ if(!isVertical && title.text && yanchor === 'bottom' && optsY <= 0) {
23698
+ hColorbarMoveTitle = outerThickness / 2;
23529
23699
 
23530
- g.selectAll('.' + cn.cboutline).attr({
23531
- x: xLeft,
23532
- y: yTopPx + opts.ypad + (titleSide === 'top' ? titleHeight : 0),
23533
- width: Math.max(thickPx, 2),
23534
- height: Math.max(outerheight - 2 * opts.ypad - titleHeight, 2)
23535
- })
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)
23714
+ .call(Color.stroke, opts.bordercolor)
23715
+ .style('stroke-width', borderwidth);
23716
+
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))
23536
23727
  .call(Color.stroke, opts.outlinecolor)
23537
23728
  .style({
23538
23729
  fill: 'none',
23539
- 'stroke-width': opts.outlinewidth
23730
+ 'stroke-width': outlinewidth
23540
23731
  });
23541
23732
 
23542
- // fix positioning for xanchor!='left'
23543
- var xoffset = ({center: 0.5, right: 1}[opts.xanchor] || 0) * outerwidth;
23544
- 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
+ }
23545
23790
 
23546
23791
  // auto margin adjustment
23547
23792
  var marginOpts = {};
23548
- var tFrac = FROM_TL[opts.yanchor];
23549
- var bFrac = FROM_BR[opts.yanchor];
23550
- if(opts.lenmode === 'pixels') {
23551
- marginOpts.y = opts.y;
23552
- marginOpts.t = outerheight * tFrac;
23553
- marginOpts.b = outerheight * bFrac;
23554
- } else {
23555
- marginOpts.t = marginOpts.b = 0;
23556
- marginOpts.yt = opts.y + opts.len * tFrac;
23557
- marginOpts.yb = opts.y - opts.len * bFrac;
23558
- }
23793
+ var lFrac = FROM_TL[xanchor];
23794
+ var rFrac = FROM_BR[xanchor];
23795
+ var tFrac = FROM_TL[yanchor];
23796
+ var bFrac = FROM_BR[yanchor];
23559
23797
 
23560
- var lFrac = FROM_TL[opts.xanchor];
23561
- var rFrac = FROM_BR[opts.xanchor];
23562
- if(opts.thicknessmode === 'pixels') {
23563
- marginOpts.x = opts.x;
23564
- marginOpts.l = outerwidth * lFrac;
23565
- marginOpts.r = outerwidth * rFrac;
23566
- } else {
23567
- var extraThickness = outerwidth - thickPx;
23568
- marginOpts.l = extraThickness * lFrac;
23569
- marginOpts.r = extraThickness * rFrac;
23570
- marginOpts.xl = opts.x - opts.thickness * lFrac;
23571
- marginOpts.xr = opts.x + opts.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
+ }
23572
23841
  }
23573
23842
 
23574
23843
  Plots.autoMargin(gd, opts._id, marginOpts);
@@ -23585,6 +23854,7 @@ function drawColorBar(g, opts, gd) {
23585
23854
  }
23586
23855
 
23587
23856
  function makeEditable(g, opts, gd) {
23857
+ var isVertical = opts.orientation === 'v';
23588
23858
  var fullLayout = gd._fullLayout;
23589
23859
  var gs = fullLayout._size;
23590
23860
  var t0, xf, yf;
@@ -23599,9 +23869,13 @@ function makeEditable(g, opts, gd) {
23599
23869
  moveFn: function(dx, dy) {
23600
23870
  g.attr('transform', t0 + strTranslate(dx, dy));
23601
23871
 
23602
- xf = dragElement.align(opts._xLeftFrac + (dx / gs.w), opts._thickFrac,
23872
+ xf = dragElement.align(
23873
+ (isVertical ? opts._uFrac : opts._vFrac) + (dx / gs.w),
23874
+ isVertical ? opts._thickFrac : opts._lenFrac,
23603
23875
  0, 1, opts.xanchor);
23604
- yf = dragElement.align(opts._yBottomFrac - (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,
23605
23879
  0, 1, opts.yanchor);
23606
23880
 
23607
23881
  var csr = dragElement.getCursor(xf, yf, opts.xanchor, opts.yanchor);
@@ -23678,6 +23952,8 @@ function calcLevels(gd, opts, zrange) {
23678
23952
  function mockColorBarAxis(gd, opts, zrange) {
23679
23953
  var fullLayout = gd._fullLayout;
23680
23954
 
23955
+ var isVertical = opts.orientation === 'v';
23956
+
23681
23957
  var cbAxisIn = {
23682
23958
  type: 'linear',
23683
23959
  range: zrange,
@@ -23708,17 +23984,19 @@ function mockColorBarAxis(gd, opts, zrange) {
23708
23984
  title: opts.title,
23709
23985
  showline: true,
23710
23986
  anchor: 'free',
23711
- side: 'right',
23987
+ side: isVertical ? 'right' : 'bottom',
23712
23988
  position: 1
23713
23989
  };
23714
23990
 
23991
+ var letter = isVertical ? 'y' : 'x';
23992
+
23715
23993
  var cbAxisOut = {
23716
23994
  type: 'linear',
23717
- _id: 'y' + opts._id
23995
+ _id: letter + opts._id
23718
23996
  };
23719
23997
 
23720
23998
  var axisOptions = {
23721
- letter: 'y',
23999
+ letter: letter,
23722
24000
  font: fullLayout.font,
23723
24001
  noHover: true,
23724
24002
  noTickson: true,
@@ -26180,7 +26458,7 @@ var TEXTOFFSETSIGN = {
26180
26458
  start: 1, end: -1, middle: 0, bottom: 1, top: -1
26181
26459
  };
26182
26460
 
26183
- function textPointPosition(s, textPosition, fontSize, markerRadius) {
26461
+ function textPointPosition(s, textPosition, fontSize, markerRadius, dontTouchParent) {
26184
26462
  var group = d3.select(s.node().parentNode);
26185
26463
 
26186
26464
  var v = textPosition.indexOf('top') !== -1 ?
@@ -26202,7 +26480,9 @@ function textPointPosition(s, textPosition, fontSize, markerRadius) {
26202
26480
 
26203
26481
  // fix the overall text group position
26204
26482
  s.attr('text-anchor', h);
26205
- group.attr('transform', strTranslate(dx, dy));
26483
+ if(!dontTouchParent) {
26484
+ group.attr('transform', strTranslate(dx, dy));
26485
+ }
26206
26486
  }
26207
26487
 
26208
26488
  function extracTextFontSize(d, trace) {
@@ -26272,7 +26552,8 @@ drawing.selectedTextStyle = function(s, trace) {
26272
26552
  var fontSize = extracTextFontSize(d, trace);
26273
26553
 
26274
26554
  Color.fill(tx, tc);
26275
- 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);
26276
26557
  });
26277
26558
  };
26278
26559
 
@@ -28303,11 +28584,13 @@ var cartesianScatterPoints = {
28303
28584
  // The actual rendering is done by private function _hover.
28304
28585
  exports.hover = function hover(gd, evt, subplot, noHoverEvent) {
28305
28586
  gd = Lib.getGraphDiv(gd);
28306
-
28587
+ // The 'target' property changes when bubbling out of Shadow DOM.
28588
+ // Throttling can delay reading the target, so we save the current value.
28589
+ var eventTarget = evt.target;
28307
28590
  Lib.throttle(
28308
28591
  gd._fullLayout._uid + constants.HOVERID,
28309
28592
  constants.HOVERMINTIME,
28310
- function() { _hover(gd, evt, subplot, noHoverEvent); }
28593
+ function() { _hover(gd, evt, subplot, noHoverEvent, eventTarget); }
28311
28594
  );
28312
28595
  };
28313
28596
 
@@ -28472,7 +28755,7 @@ exports.loneHover = function loneHover(hoverItems, opts) {
28472
28755
  };
28473
28756
 
28474
28757
  // The actual implementation is here:
28475
- function _hover(gd, evt, subplot, noHoverEvent) {
28758
+ function _hover(gd, evt, subplot, noHoverEvent, eventTarget) {
28476
28759
  if(!subplot) subplot = 'xy';
28477
28760
 
28478
28761
  // if the user passed in an array of subplots,
@@ -28591,7 +28874,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
28591
28874
  // [x|y]px: the pixels (from top left) of the mouse location
28592
28875
  // on the currently selected plot area
28593
28876
  // add pointerX|Y property for drawing the spikes in spikesnap 'cursor' situation
28594
- var hasUserCalledHover = !evt.target;
28877
+ var hasUserCalledHover = !eventTarget;
28595
28878
  var xpx, ypx;
28596
28879
 
28597
28880
  if(hasUserCalledHover) {
@@ -28608,13 +28891,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
28608
28891
  return;
28609
28892
  }
28610
28893
 
28611
- // Discover event target, traversing open shadow roots.
28612
- var target = evt.composedPath && evt.composedPath()[0];
28613
- if(!target) {
28614
- // Fallback for browsers not supporting composedPath
28615
- target = evt.target;
28616
- }
28617
- var dbb = target.getBoundingClientRect();
28894
+ var dbb = eventTarget.getBoundingClientRect();
28618
28895
 
28619
28896
  xpx = evt.clientX - dbb.left;
28620
28897
  ypx = evt.clientY - dbb.top;
@@ -29062,15 +29339,15 @@ function _hover(gd, evt, subplot, noHoverEvent) {
29062
29339
  if(!helpers.isUnifiedHover(hovermode)) {
29063
29340
  hoverAvoidOverlaps(hoverLabels, rotateLabels ? 'xa' : 'ya', fullLayout);
29064
29341
  alignHoverText(hoverLabels, rotateLabels, fullLayout._invScaleX, fullLayout._invScaleY);
29065
- } // TODO: tagName hack is needed to appease geo.js's hack of using evt.target=true
29342
+ } // TODO: tagName hack is needed to appease geo.js's hack of using eventTarget=true
29066
29343
  // we should improve the "fx" API so other plots can use it without these hack.
29067
- if(evt.target && evt.target.tagName) {
29344
+ if(eventTarget && eventTarget.tagName) {
29068
29345
  var hasClickToShow = Registry.getComponentMethod('annotations', 'hasClickToShow')(gd, newhoverdata);
29069
- overrideCursor(d3.select(evt.target), hasClickToShow ? 'pointer' : '');
29346
+ overrideCursor(d3.select(eventTarget), hasClickToShow ? 'pointer' : '');
29070
29347
  }
29071
29348
 
29072
29349
  // don't emit events if called manually
29073
- if(!evt.target || noHoverEvent || !hoverChanged(gd, evt, oldhoverdata)) return;
29350
+ if(!eventTarget || noHoverEvent || !hoverChanged(gd, evt, oldhoverdata)) return;
29074
29351
 
29075
29352
  if(oldhoverdata) {
29076
29353
  gd.emit('plotly_unhover', {
@@ -29332,7 +29609,9 @@ function createHoverText(hoverData, opts) {
29332
29609
  orientation: 'v'
29333
29610
  }
29334
29611
  };
29335
- var mockLayoutOut = {};
29612
+ var mockLayoutOut = {
29613
+ font: font
29614
+ };
29336
29615
  legendSupplyDefaults(mockLayoutIn, mockLayoutOut, gd._fullData);
29337
29616
  var mockLegend = mockLayoutOut.legend;
29338
29617
 
@@ -29373,7 +29652,8 @@ function createHoverText(hoverData, opts) {
29373
29652
 
29374
29653
  // Draw unified hover label
29375
29654
  mockLegend._inHover = true;
29376
- mockLegend._groupTitleFont = font;
29655
+ mockLegend._groupTitleFont = hoverlabel.grouptitlefont;
29656
+
29377
29657
  legendDraw(gd, mockLegend);
29378
29658
 
29379
29659
  // Position the hover
@@ -30375,9 +30655,11 @@ var isUnifiedHover = _dereq_('./helpers').isUnifiedHover;
30375
30655
  module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts) {
30376
30656
  opts = opts || {};
30377
30657
 
30658
+ var hasLegend = contOut.legend;
30659
+
30378
30660
  function inheritFontAttr(attr) {
30379
30661
  if(!opts.font[attr]) {
30380
- opts.font[attr] = contOut.legend ? contOut.legend.font[attr] : contOut.font[attr];
30662
+ opts.font[attr] = hasLegend ? contOut.legend.font[attr] : contOut.font[attr];
30381
30663
  }
30382
30664
  }
30383
30665
 
@@ -30388,7 +30670,7 @@ module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts
30388
30670
  inheritFontAttr('family');
30389
30671
  inheritFontAttr('color');
30390
30672
 
30391
- if(contOut.legend) {
30673
+ if(hasLegend) {
30392
30674
  if(!opts.bgcolor) opts.bgcolor = Color.combine(contOut.legend.bgcolor, contOut.paper_bgcolor);
30393
30675
  if(!opts.bordercolor) opts.bordercolor = contOut.legend.bordercolor;
30394
30676
  } else {
@@ -30497,11 +30779,13 @@ function castHoverinfo(trace, fullLayout, ptNumber) {
30497
30779
 
30498
30780
  var constants = _dereq_('./constants');
30499
30781
 
30500
- var fontAttrs = _dereq_('../../plots/font_attributes')({
30782
+ var fontAttrs = _dereq_('../../plots/font_attributes');
30783
+
30784
+ var font = fontAttrs({
30501
30785
  editType: 'none',
30502
30786
  });
30503
- fontAttrs.family.dflt = constants.HOVERFONT;
30504
- fontAttrs.size.dflt = constants.HOVERFONTSIZE;
30787
+ font.family.dflt = constants.HOVERFONT;
30788
+ font.size.dflt = constants.HOVERFONTSIZE;
30505
30789
 
30506
30790
  module.exports = {
30507
30791
  clickmode: {
@@ -30557,7 +30841,10 @@ module.exports = {
30557
30841
  valType: 'color',
30558
30842
  editType: 'none',
30559
30843
  },
30560
- font: fontAttrs,
30844
+ font: font,
30845
+ grouptitlefont: fontAttrs({
30846
+ editType: 'none',
30847
+ }),
30561
30848
  align: {
30562
30849
  valType: 'enumerated',
30563
30850
  values: ['left', 'right', 'auto'],
@@ -30570,6 +30857,7 @@ module.exports = {
30570
30857
  dflt: 15,
30571
30858
  editType: 'none',
30572
30859
  },
30860
+
30573
30861
  editType: 'none'
30574
30862
  },
30575
30863
  selectdirection: {
@@ -30617,6 +30905,8 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut) {
30617
30905
  }
30618
30906
 
30619
30907
  handleHoverLabelDefaults(layoutIn, layoutOut, coerce);
30908
+
30909
+ Lib.coerceFont(coerce, 'hoverlabel.grouptitlefont', layoutOut.hoverlabel.font);
30620
30910
  };
30621
30911
 
30622
30912
  },{"../../lib":242,"./hoverlabel_defaults":149,"./hovermode_defaults":150,"./layout_attributes":152}],154:[function(_dereq_,module,exports){
@@ -31500,6 +31790,9 @@ module.exports = {
31500
31790
  font: fontAttrs({
31501
31791
  editType: 'legend',
31502
31792
  }),
31793
+ grouptitlefont: fontAttrs({
31794
+ editType: 'legend',
31795
+ }),
31503
31796
  orientation: {
31504
31797
  valType: 'enumerated',
31505
31798
  values: ['v', 'h'],
@@ -31623,6 +31916,7 @@ var Registry = _dereq_('../../registry');
31623
31916
  var Lib = _dereq_('../../lib');
31624
31917
  var Template = _dereq_('../../plot_api/plot_template');
31625
31918
 
31919
+ var plotsAttrs = _dereq_('../../plots/attributes');
31626
31920
  var attributes = _dereq_('./attributes');
31627
31921
  var basePlotLayoutAttributes = _dereq_('../../plots/layout_attributes');
31628
31922
  var helpers = _dereq_('./helpers');
@@ -31630,13 +31924,30 @@ var helpers = _dereq_('./helpers');
31630
31924
 
31631
31925
  module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
31632
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
+ }));
31633
31944
 
31634
31945
  var legendTraceCount = 0;
31635
31946
  var legendReallyHasATrace = false;
31636
31947
  var defaultOrder = 'normal';
31637
31948
 
31638
31949
  for(var i = 0; i < fullData.length; i++) {
31639
- var trace = fullData[i];
31950
+ trace = fullData[i];
31640
31951
 
31641
31952
  if(!trace.visible) continue;
31642
31953
 
@@ -31663,6 +31974,8 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
31663
31974
  legendTraceCount++;
31664
31975
  }
31665
31976
  }
31977
+
31978
+ Lib.coerceFont(traceCoerce, 'legendgrouptitle.font', grouptitlefont);
31666
31979
  }
31667
31980
 
31668
31981
  if((Registry.traceIs(trace, 'bar') && layoutOut.barmode === 'stack') ||
@@ -31681,13 +31994,10 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
31681
31994
  basePlotLayoutAttributes, 'showlegend',
31682
31995
  legendReallyHasATrace && legendTraceCount > 1);
31683
31996
 
31684
- if(showLegend === false && !containerIn.uirevision) return;
31997
+ // delete legend
31998
+ if(showLegend === false) layoutOut.legend = undefined;
31685
31999
 
31686
- var containerOut = Template.newContainer(layoutOut, 'legend');
31687
-
31688
- function coerce(attr, dflt) {
31689
- return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
31690
- }
32000
+ if(showLegend === false && !containerIn.uirevision) return;
31691
32001
 
31692
32002
  coerce('uirevision', layoutOut.uirevision);
31693
32003
 
@@ -31749,7 +32059,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
31749
32059
  }
31750
32060
  };
31751
32061
 
31752
- },{"../../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){
31753
32063
  'use strict';
31754
32064
 
31755
32065
  var d3 = _dereq_('@plotly/d3');
@@ -40201,8 +40511,10 @@ function draw(gd, titleClass, options) {
40201
40511
 
40202
40512
  var elShouldExist = txt || editable;
40203
40513
 
40514
+ var hColorbarMoveTitle;
40204
40515
  if(!group) {
40205
40516
  group = Lib.ensureSingle(fullLayout._infolayer, 'g', 'g-' + titleClass);
40517
+ hColorbarMoveTitle = fullLayout._hColorbarMoveTitle;
40206
40518
  }
40207
40519
 
40208
40520
  var el = group.selectAll('text')
@@ -40226,13 +40538,17 @@ function draw(gd, titleClass, options) {
40226
40538
  function drawTitle(titleEl) {
40227
40539
  var transformVal;
40228
40540
 
40541
+ if(!transform && hColorbarMoveTitle) {
40542
+ transform = {};
40543
+ }
40544
+
40229
40545
  if(transform) {
40230
40546
  transformVal = '';
40231
40547
  if(transform.rotate) {
40232
40548
  transformVal += 'rotate(' + [transform.rotate, attributes.x, attributes.y] + ')';
40233
40549
  }
40234
- if(transform.offset) {
40235
- transformVal += strTranslate(0, transform.offset);
40550
+ if(transform.offset || hColorbarMoveTitle) {
40551
+ transformVal += strTranslate(0, (transform.offset || 0) - (hColorbarMoveTitle || 0));
40236
40552
  }
40237
40553
  } else {
40238
40554
  transformVal = null;
@@ -51704,7 +52020,7 @@ function cleanDeprecatedAttributeKeys(aobj) {
51704
52020
  if((key === 'title' || oldAxisTitleRegex.test(key) || colorbarRegex.test(key)) &&
51705
52021
  (typeof value === 'string' || typeof value === 'number')) {
51706
52022
  replace(key, key.replace('title', 'title.text'));
51707
- } else if(key.indexOf('titlefont') > -1) {
52023
+ } else if(key.indexOf('titlefont') > -1 && key.indexOf('grouptitlefont') === -1) {
51708
52024
  replace(key, key.replace('titlefont', 'title.font'));
51709
52025
  } else if(key.indexOf('titleposition') > -1) {
51710
52026
  replace(key, key.replace('titleposition', 'title.position'));
@@ -52381,7 +52697,8 @@ function findUIPattern(key, patternSpecs) {
52381
52697
  var spec = patternSpecs[i];
52382
52698
  var match = key.match(spec.pattern);
52383
52699
  if(match) {
52384
- 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};
52385
52702
  }
52386
52703
  }
52387
52704
  }
@@ -52433,26 +52750,54 @@ function valsMatch(v1, v2) {
52433
52750
 
52434
52751
  function applyUIRevisions(data, layout, oldFullData, oldFullLayout) {
52435
52752
  var layoutPreGUI = oldFullLayout._preGUI;
52436
- var key, revAttr, oldRev, newRev, match, preGUIVal, newNP, newVal;
52753
+ var key, revAttr, oldRev, newRev, match, preGUIVal, newNP, newVal, head, tail;
52437
52754
  var bothInheritAutorange = [];
52755
+ var newAutorangeIn = {};
52438
52756
  var newRangeAccepted = {};
52439
52757
  for(key in layoutPreGUI) {
52440
52758
  match = findUIPattern(key, layoutUIControlPatterns);
52441
52759
  if(match) {
52442
- revAttr = match.attr || (match.head + '.uirevision');
52760
+ head = match.head;
52761
+ tail = match.tail;
52762
+ revAttr = match.attr || (head + '.uirevision');
52443
52763
  oldRev = nestedProperty(oldFullLayout, revAttr).get();
52444
52764
  newRev = oldRev && getNewRev(revAttr, layout);
52765
+
52445
52766
  if(newRev && (newRev === oldRev)) {
52446
52767
  preGUIVal = layoutPreGUI[key];
52447
52768
  if(preGUIVal === null) preGUIVal = undefined;
52448
52769
  newNP = nestedProperty(layout, key);
52449
52770
  newVal = newNP.get();
52771
+
52450
52772
  if(valsMatch(newVal, preGUIVal)) {
52451
- if(newVal === undefined && key.substr(key.length - 9) === 'autorange') {
52452
- bothInheritAutorange.push(key.substr(0, key.length - 10));
52773
+ if(newVal === undefined && tail === 'autorange') {
52774
+ bothInheritAutorange.push(head);
52453
52775
  }
52454
52776
  newNP.set(undefinedToNull(nestedProperty(oldFullLayout, key).get()));
52455
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
+ }
52456
52801
  }
52457
52802
  }
52458
52803
  } else {
@@ -52463,12 +52808,12 @@ function applyUIRevisions(data, layout, oldFullData, oldFullLayout) {
52463
52808
  // so remove it from _preGUI for next time.
52464
52809
  delete layoutPreGUI[key];
52465
52810
 
52466
- if(key.substr(key.length - 8, 6) === 'range[') {
52467
- newRangeAccepted[key.substr(0, key.length - 9)] = 1;
52811
+ if(match && match.tail.substr(0, 6) === 'range[') {
52812
+ newRangeAccepted[match.head] = 1;
52468
52813
  }
52469
52814
  }
52470
52815
 
52471
- // Special logic for `autorange`, since it interacts with `range`:
52816
+ // More special logic for `autorange`, since it interacts with `range`:
52472
52817
  // If the new figure's matching `range` was kept, and `autorange`
52473
52818
  // wasn't supplied explicitly in either the original or the new figure,
52474
52819
  // we shouldn't alter that - but we may just have done that, so fix it.
@@ -69543,6 +69888,9 @@ module.exports = function(opts) {
69543
69888
  // TODO - that's uber hacky... better solution?
69544
69889
  };
69545
69890
 
69891
+ if(opts.autoSize) attrs.size.dflt = 'auto';
69892
+ if(opts.autoColor) attrs.color.dflt = 'auto';
69893
+
69546
69894
  if(opts.arrayOk) {
69547
69895
  attrs.family.arrayOk = true;
69548
69896
  attrs.size.arrayOk = true;
@@ -69902,6 +70250,7 @@ module.exports = {
69902
70250
  valType: 'boolean',
69903
70251
  editType: 'legend',
69904
70252
  },
70253
+
69905
70254
  colorway: {
69906
70255
  valType: 'colorlist',
69907
70256
  dflt: colorAttrs.defaults,
@@ -71314,13 +71663,7 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac
71314
71663
  );
71315
71664
 
71316
71665
  coerce('legendgroup');
71317
- var titleText = coerce('legendgrouptitle.text');
71318
- if(titleText) {
71319
- Lib.coerceFont(coerce, 'legendgrouptitle.font', Lib.extendFlat({}, layout.font, {
71320
- size: Math.round(layout.font.size * 1.1) // default to larger font size
71321
- }));
71322
- }
71323
-
71666
+ coerce('legendgrouptitle.text');
71324
71667
  coerce('legendrank');
71325
71668
 
71326
71669
  traceOut._dfltShowLegend = true;
@@ -71468,16 +71811,14 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut, formatObj) {
71468
71811
 
71469
71812
  coerce('autotypenumbers');
71470
71813
 
71471
- var globalFont = Lib.coerceFont(coerce, 'font');
71472
-
71473
- coerce('title.text', layoutOut._dfltTitle.plot);
71814
+ var font = Lib.coerceFont(coerce, 'font');
71815
+ var fontSize = font.size;
71474
71816
 
71475
- Lib.coerceFont(coerce, 'title.font', {
71476
- family: globalFont.family,
71477
- size: Math.round(globalFont.size * 1.4),
71478
- color: globalFont.color
71479
- });
71817
+ Lib.coerceFont(coerce, 'title.font', Lib.extendFlat({}, font, {
71818
+ size: Math.round(fontSize * 1.4)
71819
+ }));
71480
71820
 
71821
+ coerce('title.text', layoutOut._dfltTitle.plot);
71481
71822
  coerce('title.xref');
71482
71823
  coerce('title.yref');
71483
71824
  coerce('title.x');
@@ -76814,7 +77155,7 @@ function appendBarText(gd, plotinfo, bar, cd, i, x0, x1, y0, y1, opts, makeOnCom
76814
77155
  }
76815
77156
 
76816
77157
  transform.fontSize = font.size;
76817
- recordMinTextSize(trace.type, transform, fullLayout);
77158
+ recordMinTextSize(trace.type === 'histogram' ? 'bar' : trace.type, transform, fullLayout);
76818
77159
  calcBar.transform = transform;
76819
77160
 
76820
77161
  transition(textSelection, fullLayout, opts, makeOnCompleteCallback)
@@ -80058,6 +80399,8 @@ module.exports = function style(gd) {
80058
80399
  var barAttrs = _dereq_('../bar/attributes');
80059
80400
  var axisHoverFormat = _dereq_('../../plots/cartesian/axis_format_attributes').axisHoverFormat;
80060
80401
  var hovertemplateAttrs = _dereq_('../../plots/template_attributes').hovertemplateAttrs;
80402
+ var texttemplateAttrs = _dereq_('../../plots/template_attributes').texttemplateAttrs;
80403
+ var fontAttrs = _dereq_('../../plots/font_attributes');
80061
80404
  var makeBinAttrs = _dereq_('./bin_attributes');
80062
80405
  var constants = _dereq_('./constants');
80063
80406
  var extendFlat = _dereq_('../../lib/extend').extendFlat;
@@ -80152,6 +80495,41 @@ module.exports = {
80152
80495
  keys: constants.eventDataKeys
80153
80496
  }),
80154
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
+
80155
80533
  marker: barAttrs.marker,
80156
80534
 
80157
80535
  offsetgroup: barAttrs.offsetgroup,
@@ -80165,7 +80543,7 @@ module.exports = {
80165
80543
  }
80166
80544
  };
80167
80545
 
80168
- },{"../../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){
80169
80547
  'use strict';
80170
80548
 
80171
80549
 
@@ -81288,6 +81666,7 @@ var Registry = _dereq_('../../registry');
81288
81666
  var Lib = _dereq_('../../lib');
81289
81667
  var Color = _dereq_('../../components/color');
81290
81668
 
81669
+ var handleText = _dereq_('../bar/defaults').handleText;
81291
81670
  var handleStyleDefaults = _dereq_('../bar/style_defaults');
81292
81671
  var attributes = _dereq_('./attributes');
81293
81672
 
@@ -81306,6 +81685,16 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
81306
81685
  }
81307
81686
 
81308
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
+
81309
81698
  coerce('hovertext');
81310
81699
  coerce('hovertemplate');
81311
81700
  coerce('xhoverformat');
@@ -81349,7 +81738,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
81349
81738
  errorBarsSupplyDefaults(traceIn, traceOut, lineColor || Color.defaultLine, {axis: 'x', inherit: 'y'});
81350
81739
  };
81351
81740
 
81352
- },{"../../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){
81353
81742
  'use strict';
81354
81743
 
81355
81744
  module.exports = function eventData(out, pt, trace, cd, pointNumber) {
@@ -83801,7 +84190,6 @@ function calc(gd, trace) {
83801
84190
  v = vals[i];
83802
84191
  if(!isNumeric(v)) continue;
83803
84192
  v = +v;
83804
- if(v < 0) continue;
83805
84193
  } else v = 1;
83806
84194
 
83807
84195
  label = labels[i];
@@ -83838,6 +84226,9 @@ function calc(gd, trace) {
83838
84226
  }
83839
84227
  }
83840
84228
 
84229
+ // Drop aggregate sums of value 0 or less
84230
+ cd = cd.filter(function(elem) { return elem.v >= 0; });
84231
+
83841
84232
  var shouldSort = (trace.type === 'funnelarea') ? isAggregated : trace.sort;
83842
84233
  if(shouldSort) cd.sort(function(a, b) { return b.v - a.v; });
83843
84234
 
@@ -90219,7 +90610,7 @@ function getSortFunc(opts, d2c) {
90219
90610
  'use strict';
90220
90611
 
90221
90612
  // package version injected by `npm run preprocess`
90222
- exports.version = '2.6.2';
90613
+ exports.version = '2.8.0';
90223
90614
 
90224
90615
  },{}]},{},[12])(12)
90225
90616
  });