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 (basic) v2.6.3
2
+ * plotly.js (basic) v2.8.1
3
3
  * Copyright 2012-2021, Plotly, Inc.
4
4
  * All rights reserved.
5
5
  * Licensed under the MIT license
@@ -21564,13 +21564,11 @@ var overrideAll = _dereq_('../../plot_api/edit_types').overrideAll;
21564
21564
 
21565
21565
 
21566
21566
  module.exports = overrideAll({
21567
- // TODO: only right is supported currently
21568
- // orient: {
21569
- // valType: 'enumerated',
21570
- // values: ['left', 'right', 'top', 'bottom'],
21571
- // dflt: 'right',
21572
- //
21573
- // },
21567
+ orientation: {
21568
+ valType: 'enumerated',
21569
+ values: ['h', 'v'],
21570
+ dflt: 'v',
21571
+ },
21574
21572
  thicknessmode: {
21575
21573
  valType: 'enumerated',
21576
21574
  values: ['fraction', 'pixels'],
@@ -21593,14 +21591,12 @@ module.exports = overrideAll({
21593
21591
  },
21594
21592
  x: {
21595
21593
  valType: 'number',
21596
- dflt: 1.02,
21597
21594
  min: -2,
21598
21595
  max: 3,
21599
21596
  },
21600
21597
  xanchor: {
21601
21598
  valType: 'enumerated',
21602
21599
  values: ['left', 'center', 'right'],
21603
- dflt: 'left',
21604
21600
  },
21605
21601
  xpad: {
21606
21602
  valType: 'number',
@@ -21609,14 +21605,12 @@ module.exports = overrideAll({
21609
21605
  },
21610
21606
  y: {
21611
21607
  valType: 'number',
21612
- dflt: 0.5,
21613
21608
  min: -2,
21614
21609
  max: 3,
21615
21610
  },
21616
21611
  yanchor: {
21617
21612
  valType: 'enumerated',
21618
21613
  values: ['top', 'middle', 'bottom'],
21619
- dflt: 'middle',
21620
21614
  },
21621
21615
  ypad: {
21622
21616
  valType: 'number',
@@ -21648,15 +21642,21 @@ module.exports = overrideAll({
21648
21642
  ticks: extendFlat({}, axesAttrs.ticks, {dflt: ''}),
21649
21643
  ticklabeloverflow: extendFlat({}, axesAttrs.ticklabeloverflow, {
21650
21644
  }),
21645
+
21646
+ // ticklabelposition: not used directly, as values depend on orientation
21647
+ // left/right options are for x axes, and top/bottom options are for y axes
21651
21648
  ticklabelposition: {
21652
21649
  valType: 'enumerated',
21653
21650
  values: [
21654
21651
  'outside', 'inside',
21655
21652
  'outside top', 'inside top',
21653
+ 'outside left', 'inside left',
21654
+ 'outside right', 'inside right',
21656
21655
  'outside bottom', 'inside bottom'
21657
21656
  ],
21658
21657
  dflt: 'outside',
21659
21658
  },
21659
+
21660
21660
  ticklen: axesAttrs.ticklen,
21661
21661
  tickwidth: axesAttrs.tickwidth,
21662
21662
  tickcolor: axesAttrs.tickcolor,
@@ -21683,7 +21683,6 @@ module.exports = overrideAll({
21683
21683
  side: {
21684
21684
  valType: 'enumerated',
21685
21685
  values: ['right', 'top', 'bottom'],
21686
- dflt: 'top',
21687
21686
  }
21688
21687
  },
21689
21688
 
@@ -21742,23 +21741,30 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
21742
21741
  return Lib.coerce(colorbarIn, colorbarOut, attributes, attr, dflt);
21743
21742
  }
21744
21743
 
21744
+ var margin = layout.margin || {t: 0, b: 0, l: 0, r: 0};
21745
+ var w = layout.width - margin.l - margin.r;
21746
+ var h = layout.height - margin.t - margin.b;
21747
+
21748
+ var orientation = coerce('orientation');
21749
+ var isVertical = orientation === 'v';
21750
+
21745
21751
  var thicknessmode = coerce('thicknessmode');
21746
21752
  coerce('thickness', (thicknessmode === 'fraction') ?
21747
- 30 / (layout.width - layout.margin.l - layout.margin.r) :
21753
+ 30 / (isVertical ? w : h) :
21748
21754
  30
21749
21755
  );
21750
21756
 
21751
21757
  var lenmode = coerce('lenmode');
21752
21758
  coerce('len', (lenmode === 'fraction') ?
21753
21759
  1 :
21754
- layout.height - layout.margin.t - layout.margin.b
21760
+ isVertical ? h : w
21755
21761
  );
21756
21762
 
21757
- coerce('x');
21758
- coerce('xanchor');
21763
+ coerce('x', isVertical ? 1.02 : 0.5);
21764
+ coerce('xanchor', isVertical ? 'left' : 'center');
21759
21765
  coerce('xpad');
21760
- coerce('y');
21761
- coerce('yanchor');
21766
+ coerce('y', isVertical ? 0.5 : 1.02);
21767
+ coerce('yanchor', isVertical ? 'middle' : 'bottom');
21762
21768
  coerce('ypad');
21763
21769
  Lib.noneOrAll(colorbarIn, colorbarOut, ['x', 'y']);
21764
21770
 
@@ -21768,7 +21774,22 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
21768
21774
  coerce('borderwidth');
21769
21775
  coerce('bgcolor');
21770
21776
 
21771
- var ticklabelposition = coerce('ticklabelposition');
21777
+ var ticklabelposition = Lib.coerce(colorbarIn, colorbarOut, {
21778
+ ticklabelposition: {
21779
+ valType: 'enumerated',
21780
+ dflt: 'outside',
21781
+ values: isVertical ? [
21782
+ 'outside', 'inside',
21783
+ 'outside top', 'inside top',
21784
+ 'outside bottom', 'inside bottom'
21785
+ ] : [
21786
+ 'outside', 'inside',
21787
+ 'outside left', 'inside left',
21788
+ 'outside right', 'inside right'
21789
+ ]
21790
+ }
21791
+ }, 'ticklabelposition');
21792
+
21772
21793
  coerce('ticklabeloverflow', ticklabelposition.indexOf('inside') !== -1 ? 'hide past domain' : 'hide past div');
21773
21794
 
21774
21795
  handleTickValueDefaults(colorbarIn, colorbarOut, coerce, 'linear');
@@ -21790,7 +21811,7 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
21790
21811
  size: Lib.bigFont(tickFont.size)
21791
21812
  });
21792
21813
  Lib.coerceFont(coerce, 'title.font', dfltTitleFont);
21793
- coerce('title.side');
21814
+ coerce('title.side', isVertical ? 'top' : 'right');
21794
21815
  };
21795
21816
 
21796
21817
  },{"../../lib":232,"../../plot_api/plot_template":268,"../../plots/cartesian/prefix_suffix_defaults":298,"../../plots/cartesian/tick_label_defaults":303,"../../plots/cartesian/tick_mark_defaults":304,"../../plots/cartesian/tick_value_defaults":305,"./attributes":103}],106:[function(_dereq_,module,exports){
@@ -21963,18 +21984,20 @@ function makeColorBarData(gd) {
21963
21984
  }
21964
21985
 
21965
21986
  function drawColorBar(g, opts, gd) {
21987
+ var isVertical = opts.orientation === 'v';
21966
21988
  var len = opts.len;
21967
21989
  var lenmode = opts.lenmode;
21968
21990
  var thickness = opts.thickness;
21969
21991
  var thicknessmode = opts.thicknessmode;
21970
21992
  var outlinewidth = opts.outlinewidth;
21971
21993
  var borderwidth = opts.borderwidth;
21994
+ var bgcolor = opts.bgcolor;
21972
21995
  var xanchor = opts.xanchor;
21973
21996
  var yanchor = opts.yanchor;
21974
21997
  var xpad = opts.xpad;
21975
21998
  var ypad = opts.ypad;
21976
21999
  var optsX = opts.x;
21977
- var optsY = opts.y;
22000
+ var optsY = isVertical ? opts.y : 1 - opts.y;
21978
22001
 
21979
22002
  var fullLayout = gd._fullLayout;
21980
22003
  var gs = fullLayout._size;
@@ -22005,23 +22028,35 @@ function drawColorBar(g, opts, gd) {
22005
22028
  // when the colorbar itself is pushing the margins.
22006
22029
  // but then the fractional size is calculated based on the
22007
22030
  // actual graph size, so that the axes will size correctly.
22008
- var thickPx = Math.round(thickness * (thicknessmode === 'fraction' ? gs.w : 1));
22009
- var thickFrac = thickPx / gs.w;
22010
- var lenPx = Math.round(len * (lenmode === 'fraction' ? gs.h : 1));
22011
- var lenFrac = lenPx / gs.h;
22012
- var xpadFrac = xpad / gs.w;
22013
- var yExtraPx = (borderwidth + outlinewidth) / 2;
22014
- var ypadFrac = ypad / gs.h;
22031
+ var thickPx = Math.round(thickness * (thicknessmode === 'fraction' ? (isVertical ? gs.w : gs.h) : 1));
22032
+ var thickFrac = thickPx / (isVertical ? gs.w : gs.h);
22033
+ var lenPx = Math.round(len * (lenmode === 'fraction' ? (isVertical ? gs.h : gs.w) : 1));
22034
+ var lenFrac = lenPx / (isVertical ? gs.h : gs.w);
22015
22035
 
22016
22036
  // x positioning: do it initially just for left anchor,
22017
22037
  // then fix at the end (since we don't know the width yet)
22018
- var uPx = Math.round(optsX * gs.w + xpad);
22019
- // for dragging... this is getting a little muddled...
22020
- var uFrac = optsX - thickFrac * ({center: 0.5, right: 1}[xanchor] || 0);
22038
+ var uPx = Math.round(isVertical ?
22039
+ optsX * gs.w + xpad :
22040
+ optsY * gs.h + ypad
22041
+ );
22021
22042
 
22022
- // y positioning we can do correctly from the start
22023
- var vFrac = optsY + lenFrac * (({top: -0.5, bottom: 0.5}[yanchor] || 0) - 0.5);
22024
- var vPx = Math.round(gs.h * (1 - vFrac));
22043
+ var xRatio = {center: 0.5, right: 1}[xanchor] || 0;
22044
+ var yRatio = {top: 1, middle: 0.5}[yanchor] || 0;
22045
+
22046
+ // for dragging... this is getting a little muddled...
22047
+ var uFrac = isVertical ?
22048
+ optsX - xRatio * thickFrac :
22049
+ optsY - yRatio * thickFrac;
22050
+
22051
+ // y/x positioning (for v/h) we can do correctly from the start
22052
+ var vFrac = isVertical ?
22053
+ optsY - yRatio * lenFrac :
22054
+ optsX - xRatio * lenFrac;
22055
+
22056
+ var vPx = Math.round(isVertical ?
22057
+ gs.h * (1 - vFrac) :
22058
+ gs.w * vFrac
22059
+ );
22025
22060
 
22026
22061
  // stash a few things for makeEditable
22027
22062
  opts._lenFrac = lenFrac;
@@ -22034,12 +22069,23 @@ function drawColorBar(g, opts, gd) {
22034
22069
 
22035
22070
  // position can't go in through supplyDefaults
22036
22071
  // because that restricts it to [0,1]
22037
- ax.position = optsX + xpadFrac + thickFrac;
22072
+ ax.position = thickFrac + (isVertical ?
22073
+ optsX + xpad / gs.w :
22074
+ optsY + ypad / gs.h
22075
+ );
22076
+
22077
+ var topOrBottom = ['top', 'bottom'].indexOf(titleSide) !== -1;
22078
+
22079
+ if(isVertical && topOrBottom) {
22080
+ ax.title.side = titleSide;
22081
+ ax.titlex = optsX + xpad / gs.w;
22082
+ ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypad / gs.h : ypad / gs.h);
22083
+ }
22038
22084
 
22039
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
22085
+ if(!isVertical && !topOrBottom) {
22040
22086
  ax.title.side = titleSide;
22041
- ax.titlex = optsX + xpadFrac;
22042
- ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
22087
+ ax.titley = optsY + ypad / gs.h;
22088
+ ax.titlex = vFrac + xpad / gs.w; // right side
22043
22089
  }
22044
22090
 
22045
22091
  if(line.color && opts.tickmode === 'auto') {
@@ -22064,9 +22110,12 @@ function drawColorBar(g, opts, gd) {
22064
22110
 
22065
22111
  // set domain after init, because we may want to
22066
22112
  // allow it outside [0,1]
22067
- ax.domain = [
22068
- vFrac + ypadFrac,
22069
- vFrac + lenFrac - ypadFrac
22113
+ ax.domain = isVertical ? [
22114
+ vFrac + ypad / gs.h,
22115
+ vFrac + lenFrac - ypad / gs.h
22116
+ ] : [
22117
+ vFrac + xpad / gs.w,
22118
+ vFrac + lenFrac - xpad / gs.w
22070
22119
  ];
22071
22120
 
22072
22121
  ax.setScale();
@@ -22076,9 +22125,13 @@ function drawColorBar(g, opts, gd) {
22076
22125
  var titleCont = g.select('.' + cn.cbtitleunshift)
22077
22126
  .attr('transform', strTranslate(-Math.round(gs.l), -Math.round(gs.t)));
22078
22127
 
22128
+ var ticklabelposition = ax.ticklabelposition;
22129
+ var titleFontSize = ax.title.font.size;
22130
+
22079
22131
  var axLayer = g.select('.' + cn.cbaxis);
22080
22132
  var titleEl;
22081
22133
  var titleHeight = 0;
22134
+ var titleWidth = 0;
22082
22135
 
22083
22136
  function drawTitle(titleClass, titleOpts) {
22084
22137
  var dfltTitleOpts = {
@@ -22103,54 +22156,98 @@ function drawColorBar(g, opts, gd) {
22103
22156
  }
22104
22157
 
22105
22158
  function drawDummyTitle() {
22106
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
22107
- // draw the title so we know how much room it needs
22108
- // when we squish the axis. This one only applies to
22109
- // top or bottom titles, not right side.
22110
- var x = gs.l + (optsX + xpadFrac) * gs.w;
22111
- var fontSize = ax.title.font.size;
22112
- var y;
22159
+ // draw the title so we know how much room it needs
22160
+ // when we squish the axis.
22161
+ // On vertical colorbars this only applies to top or bottom titles, not right side.
22162
+ // On horizontal colorbars this only applies to right, etc.
22163
+
22164
+ if(
22165
+ (isVertical && topOrBottom) ||
22166
+ (!isVertical && !topOrBottom)
22167
+ ) {
22168
+ var x, y;
22113
22169
 
22114
22170
  if(titleSide === 'top') {
22115
- y = (1 - (vFrac + lenFrac - ypadFrac)) * gs.h +
22116
- gs.t + 3 + fontSize * 0.75;
22117
- } else {
22118
- y = (1 - (vFrac + ypadFrac)) * gs.h +
22119
- gs.t - 3 - fontSize * 0.25;
22171
+ x = xpad + gs.l + gs.w * optsX;
22172
+ y = ypad + gs.t + gs.h * (1 - vFrac - lenFrac) + 3 + titleFontSize * 0.75;
22120
22173
  }
22174
+
22175
+ if(titleSide === 'bottom') {
22176
+ x = xpad + gs.l + gs.w * optsX;
22177
+ y = ypad + gs.t + gs.h * (1 - vFrac) - 3 - titleFontSize * 0.25;
22178
+ }
22179
+
22180
+ if(titleSide === 'right') {
22181
+ y = ypad + gs.t + gs.h * optsY + 3 + titleFontSize * 0.75;
22182
+ x = xpad + gs.l + gs.w * vFrac;
22183
+ }
22184
+
22121
22185
  drawTitle(ax._id + 'title', {
22122
- attributes: {x: x, y: y, 'text-anchor': 'start'}
22186
+ attributes: {x: x, y: y, 'text-anchor': isVertical ? 'start' : 'middle'}
22123
22187
  });
22124
22188
  }
22125
22189
  }
22126
22190
 
22127
22191
  function drawCbTitle() {
22128
- if(['top', 'bottom'].indexOf(titleSide) === -1) {
22129
- var fontSize = ax.title.font.size;
22130
- var y = ax._offset + ax._length / 2;
22131
- var x = gs.l + (ax.position || 0) * gs.w + ((ax.side === 'right') ?
22132
- 10 + fontSize * ((ax.showticklabels ? 1 : 0.5)) :
22133
- -10 - fontSize * ((ax.showticklabels ? 0.5 : 0)));
22134
-
22135
- // the 'h' + is a hack to get around the fact that
22136
- // convertToTspans rotates any 'y...' class by 90 degrees.
22137
- // TODO: find a better way to control this.
22138
- drawTitle('h' + ax._id + 'title', {
22192
+ if(
22193
+ (isVertical && !topOrBottom) ||
22194
+ (!isVertical && topOrBottom)
22195
+ ) {
22196
+ var pos = ax.position || 0;
22197
+ var mid = ax._offset + ax._length / 2;
22198
+ var x, y;
22199
+
22200
+ if(titleSide === 'right') {
22201
+ y = mid;
22202
+ x = gs.l + gs.w * pos + 10 + titleFontSize * (
22203
+ ax.showticklabels ? 1 : 0.5
22204
+ );
22205
+ } else {
22206
+ x = mid;
22207
+
22208
+ if(titleSide === 'bottom') {
22209
+ y = gs.t + gs.h * pos + 10 + (
22210
+ ticklabelposition.indexOf('inside') === -1 ?
22211
+ ax.tickfont.size :
22212
+ 0
22213
+ ) + (
22214
+ ax.ticks !== 'intside' ?
22215
+ opts.ticklen || 0 :
22216
+ 0
22217
+ );
22218
+ }
22219
+
22220
+ if(titleSide === 'top') {
22221
+ var nlines = title.text.split('<br>').length;
22222
+ y = gs.t + gs.h * pos + 10 - thickPx - LINE_SPACING * titleFontSize * nlines;
22223
+ }
22224
+ }
22225
+
22226
+ drawTitle((isVertical ?
22227
+ // the 'h' + is a hack to get around the fact that
22228
+ // convertToTspans rotates any 'y...' class by 90 degrees.
22229
+ // TODO: find a better way to control this.
22230
+ 'h' :
22231
+ 'v'
22232
+ ) + ax._id + 'title', {
22139
22233
  avoid: {
22140
22234
  selection: d3.select(gd).selectAll('g.' + ax._id + 'tick'),
22141
22235
  side: titleSide,
22142
- offsetLeft: gs.l,
22143
- offsetTop: 0,
22144
- maxShift: fullLayout.width
22236
+ offsetTop: isVertical ? 0 : gs.t,
22237
+ offsetLeft: isVertical ? gs.l : 0,
22238
+ maxShift: isVertical ? fullLayout.width : fullLayout.height
22145
22239
  },
22146
22240
  attributes: {x: x, y: y, 'text-anchor': 'middle'},
22147
- transform: {rotate: '-90', offset: 0}
22241
+ transform: {rotate: isVertical ? -90 : 0, offset: 0}
22148
22242
  });
22149
22243
  }
22150
22244
  }
22151
22245
 
22152
22246
  function drawAxis() {
22153
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
22247
+ if(
22248
+ (!isVertical && !topOrBottom) ||
22249
+ (isVertical && topOrBottom)
22250
+ ) {
22154
22251
  // squish the axis top to make room for the title
22155
22252
  var titleGroup = g.select('.' + cn.cbtitle);
22156
22253
  var titleText = titleGroup.select('text');
@@ -22162,39 +22259,63 @@ function drawColorBar(g, opts, gd) {
22162
22259
  if(titleText.node()) {
22163
22260
  lineSize = parseInt(titleText.node().style.fontSize, 10) * LINE_SPACING;
22164
22261
  }
22262
+
22263
+ var bb;
22165
22264
  if(mathJaxNode) {
22166
- titleHeight = Drawing.bBox(mathJaxNode).height;
22265
+ bb = Drawing.bBox(mathJaxNode);
22266
+ titleWidth = bb.width;
22267
+ titleHeight = bb.height;
22167
22268
  if(titleHeight > lineSize) {
22168
22269
  // not entirely sure how mathjax is doing
22169
22270
  // vertical alignment, but this seems to work.
22170
22271
  titleTrans[1] -= (titleHeight - lineSize) / 2;
22171
22272
  }
22172
22273
  } else if(titleText.node() && !titleText.classed(cn.jsPlaceholder)) {
22173
- titleHeight = Drawing.bBox(titleText.node()).height;
22274
+ bb = Drawing.bBox(titleText.node());
22275
+ titleWidth = bb.width;
22276
+ titleHeight = bb.height;
22174
22277
  }
22175
- if(titleHeight) {
22176
- // buffer btwn colorbar and title
22177
- // TODO: configurable
22178
- titleHeight += 5;
22179
22278
 
22180
- if(titleSide === 'top') {
22181
- ax.domain[1] -= titleHeight / gs.h;
22182
- titleTrans[1] *= -1;
22183
- } else {
22184
- ax.domain[0] += titleHeight / gs.h;
22185
- var nlines = svgTextUtils.lineCount(titleText);
22186
- titleTrans[1] += (1 - nlines) * lineSize;
22279
+ if(isVertical) {
22280
+ if(titleHeight) {
22281
+ // buffer btwn colorbar and title
22282
+ // TODO: configurable
22283
+ titleHeight += 5;
22284
+
22285
+ if(titleSide === 'top') {
22286
+ ax.domain[1] -= titleHeight / gs.h;
22287
+ titleTrans[1] *= -1;
22288
+ } else {
22289
+ ax.domain[0] += titleHeight / gs.h;
22290
+ var nlines = svgTextUtils.lineCount(titleText);
22291
+ titleTrans[1] += (1 - nlines) * lineSize;
22292
+ }
22293
+
22294
+ titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
22295
+ ax.setScale();
22187
22296
  }
22297
+ } else { // horizontal colorbars
22298
+ if(titleWidth) {
22299
+ if(titleSide === 'right') {
22300
+ ax.domain[0] += (titleWidth + titleFontSize / 2) / gs.w;
22301
+ }
22188
22302
 
22189
- titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
22190
- ax.setScale();
22303
+ titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
22304
+ ax.setScale();
22305
+ }
22191
22306
  }
22192
22307
  }
22193
22308
 
22194
22309
  g.selectAll('.' + cn.cbfills + ',.' + cn.cblines)
22195
- .attr('transform', strTranslate(0, Math.round(gs.h * (1 - ax.domain[1]))));
22310
+ .attr('transform', isVertical ?
22311
+ strTranslate(0, Math.round(gs.h * (1 - ax.domain[1]))) :
22312
+ strTranslate(Math.round(gs.w * ax.domain[0]), 0)
22313
+ );
22196
22314
 
22197
- axLayer.attr('transform', strTranslate(0, Math.round(-gs.t)));
22315
+ axLayer.attr('transform', isVertical ?
22316
+ strTranslate(0, Math.round(-gs.t)) :
22317
+ strTranslate(Math.round(-gs.l), 0)
22318
+ );
22198
22319
 
22199
22320
  var fills = g.select('.' + cn.cbfills)
22200
22321
  .selectAll('rect.' + cn.cbfill)
@@ -22220,20 +22341,22 @@ function drawColorBar(g, opts, gd) {
22220
22341
 
22221
22342
  // offset the side adjoining the next rectangle so they
22222
22343
  // overlap, to prevent antialiasing gaps
22223
- z[1] = Lib.constrain(z[1] + (z[1] > z[0]) ? 1 : -1, zBounds[0], zBounds[1]);
22224
-
22344
+ if(isVertical) {
22345
+ z[1] = Lib.constrain(z[1] + (z[1] > z[0]) ? 1 : -1, zBounds[0], zBounds[1]);
22346
+ } /* else {
22347
+ // TODO: horizontal case
22348
+ } */
22225
22349
 
22226
22350
  // Colorbar cannot currently support opacities so we
22227
22351
  // use an opaque fill even when alpha channels present
22228
- var fillEl = d3.select(this).attr({
22229
- x: uPx,
22230
- width: Math.max(thickPx, 2),
22231
- y: d3.min(z),
22232
- height: Math.max(d3.max(z) - d3.min(z), 2),
22233
- });
22352
+ var fillEl = d3.select(this)
22353
+ .attr(isVertical ? 'x' : 'y', uPx)
22354
+ .attr(isVertical ? 'y' : 'x', d3.min(z))
22355
+ .attr(isVertical ? 'width' : 'height', Math.max(thickPx, 2))
22356
+ .attr(isVertical ? 'height' : 'width', Math.max(d3.max(z) - d3.min(z), 2));
22234
22357
 
22235
22358
  if(opts._fillgradient) {
22236
- Drawing.gradient(fillEl, gd, opts._id, 'vertical', opts._fillgradient, 'fill');
22359
+ Drawing.gradient(fillEl, gd, opts._id, isVertical ? 'vertical' : 'horizontalreversed', opts._fillgradient, 'fill');
22237
22360
  } else {
22238
22361
  // tinycolor can't handle exponents and
22239
22362
  // at this scale, removing it makes no difference.
@@ -22249,9 +22372,15 @@ function drawColorBar(g, opts, gd) {
22249
22372
  .classed(cn.cbline, true);
22250
22373
  lines.exit().remove();
22251
22374
  lines.each(function(d) {
22375
+ var a = uPx;
22376
+ var b = (Math.round(ax.c2p(d)) + (line.width / 2) % 1);
22377
+
22252
22378
  d3.select(this)
22253
- .attr('d', 'M' + uPx + ',' +
22254
- (Math.round(ax.c2p(d)) + (line.width / 2) % 1) + 'h' + thickPx)
22379
+ .attr('d', 'M' +
22380
+ (isVertical ? a + ',' + b : b + ',' + a) +
22381
+ (isVertical ? 'h' : 'v') +
22382
+ thickPx
22383
+ )
22255
22384
  .call(Drawing.lineGroupStyle, line.width, lineColormap(d), line.dash);
22256
22385
  });
22257
22386
 
@@ -22284,82 +22413,211 @@ function drawColorBar(g, opts, gd) {
22284
22413
  // TODO: why are we redrawing multiple times now with this?
22285
22414
  // I guess autoMargin doesn't like being post-promise?
22286
22415
  function positionCB() {
22416
+ var bb;
22287
22417
  var innerThickness = thickPx + outlinewidth / 2;
22288
- if(ax.ticklabelposition.indexOf('inside') === -1) {
22289
- innerThickness += Drawing.bBox(axLayer.node()).width;
22418
+ if(ticklabelposition.indexOf('inside') === -1) {
22419
+ bb = Drawing.bBox(axLayer.node());
22420
+ innerThickness += isVertical ? bb.width : bb.height;
22290
22421
  }
22291
22422
 
22292
22423
  titleEl = titleCont.select('text');
22293
22424
 
22425
+ var titleWidth = 0;
22426
+
22427
+ var topSideVertical = isVertical && titleSide === 'top';
22428
+ var rightSideHorizontal = !isVertical && titleSide === 'right';
22429
+
22430
+ var moveY = 0;
22431
+
22294
22432
  if(titleEl.node() && !titleEl.classed(cn.jsPlaceholder)) {
22433
+ var _titleHeight;
22434
+
22295
22435
  var mathJaxNode = titleCont.select('.h' + ax._id + 'title-math-group').node();
22296
- var titleWidth;
22297
- if(mathJaxNode && ['top', 'bottom'].indexOf(titleSide) !== -1) {
22298
- titleWidth = Drawing.bBox(mathJaxNode).width;
22436
+ if(mathJaxNode && (
22437
+ (isVertical && topOrBottom) ||
22438
+ (!isVertical && !topOrBottom)
22439
+ )) {
22440
+ bb = Drawing.bBox(mathJaxNode);
22441
+ titleWidth = bb.width;
22442
+ _titleHeight = bb.height;
22299
22443
  } else {
22300
22444
  // note: the formula below works for all title sides,
22301
22445
  // (except for top/bottom mathjax, above)
22302
22446
  // but the weird gs.l is because the titleunshift
22303
22447
  // transform gets removed by Drawing.bBox
22304
- titleWidth = Drawing.bBox(titleCont.node()).right - uPx - gs.l;
22448
+ bb = Drawing.bBox(titleCont.node());
22449
+ titleWidth = bb.right - gs.l - (isVertical ? uPx : vPx);
22450
+ _titleHeight = bb.bottom - gs.t - (isVertical ? vPx : uPx);
22451
+
22452
+ if(
22453
+ !isVertical && titleSide === 'top'
22454
+ ) {
22455
+ innerThickness += bb.height;
22456
+ moveY = bb.height;
22457
+ }
22305
22458
  }
22306
- innerThickness = Math.max(innerThickness, titleWidth);
22459
+
22460
+ if(rightSideHorizontal) {
22461
+ titleEl.attr('transform', strTranslate(titleWidth / 2 + titleFontSize / 2, 0));
22462
+
22463
+ titleWidth *= 2;
22464
+ }
22465
+
22466
+ innerThickness = Math.max(innerThickness,
22467
+ isVertical ? titleWidth : _titleHeight
22468
+ );
22307
22469
  }
22308
22470
 
22309
- var outerThickness = 2 * xpad + innerThickness + borderwidth + outlinewidth / 2;
22471
+ var outerThickness = (isVertical ?
22472
+ xpad :
22473
+ ypad
22474
+ ) * 2 + innerThickness + borderwidth + outlinewidth / 2;
22310
22475
 
22311
- g.select('.' + cn.cbbg).attr({
22312
- x: uPx - xpad - (borderwidth + outlinewidth) / 2,
22313
- y: vPx - lenPx - yExtraPx,
22314
- width: Math.max(outerThickness, 2),
22315
- height: Math.max(lenPx + 2 * yExtraPx, 2)
22316
- })
22317
- .call(Color.fill, opts.bgcolor)
22476
+ var hColorbarMoveTitle = 0;
22477
+ if(!isVertical && title.text && yanchor === 'bottom' && optsY <= 0) {
22478
+ hColorbarMoveTitle = outerThickness / 2;
22479
+
22480
+ outerThickness += hColorbarMoveTitle;
22481
+ moveY += hColorbarMoveTitle;
22482
+ }
22483
+ fullLayout._hColorbarMoveTitle = hColorbarMoveTitle;
22484
+ fullLayout._hColorbarMoveCBTitle = moveY;
22485
+
22486
+ var extraW = borderwidth + outlinewidth;
22487
+
22488
+ g.select('.' + cn.cbbg)
22489
+ .attr('x', (isVertical ? uPx : vPx) - extraW / 2 - (isVertical ? xpad : 0))
22490
+ .attr('y', (isVertical ? vPx : uPx) - (isVertical ? lenPx : ypad + moveY - hColorbarMoveTitle))
22491
+ .attr(isVertical ? 'width' : 'height', Math.max(outerThickness - hColorbarMoveTitle, 2))
22492
+ .attr(isVertical ? 'height' : 'width', Math.max(lenPx + extraW, 2))
22493
+ .call(Color.fill, bgcolor)
22318
22494
  .call(Color.stroke, opts.bordercolor)
22319
22495
  .style('stroke-width', borderwidth);
22320
22496
 
22321
- g.selectAll('.' + cn.cboutline).attr({
22322
- x: uPx,
22323
- y: vPx - lenPx + ypad + (titleSide === 'top' ? titleHeight : 0),
22324
- width: Math.max(thickPx, 2),
22325
- height: Math.max(lenPx - 2 * ypad - titleHeight, 2)
22326
- })
22497
+ var moveX = rightSideHorizontal ? Math.max(titleWidth - 10, 0) : 0;
22498
+
22499
+ g.selectAll('.' + cn.cboutline)
22500
+ .attr('x', (isVertical ? uPx : vPx + xpad) + moveX)
22501
+ .attr('y', (isVertical ? vPx + ypad - lenPx : uPx) + (topSideVertical ? titleHeight : 0))
22502
+ .attr(isVertical ? 'width' : 'height', Math.max(thickPx, 2))
22503
+ .attr(isVertical ? 'height' : 'width', Math.max(lenPx - (isVertical ?
22504
+ 2 * ypad + titleHeight :
22505
+ 2 * xpad + moveX
22506
+ ), 2))
22327
22507
  .call(Color.stroke, opts.outlinecolor)
22328
22508
  .style({
22329
22509
  fill: 'none',
22330
22510
  'stroke-width': outlinewidth
22331
22511
  });
22332
22512
 
22333
- // fix positioning for xanchor!='left'
22334
- var xoffset = ({center: 0.5, right: 1}[xanchor] || 0) * outerThickness;
22335
- g.attr('transform', strTranslate(gs.l - xoffset, gs.t));
22513
+ g.attr('transform', strTranslate(
22514
+ gs.l - (isVertical ? xRatio * outerThickness : 0),
22515
+ gs.t - (isVertical ? 0 : (1 - yRatio) * outerThickness - moveY)
22516
+ ));
22517
+
22518
+ if(!isVertical && (
22519
+ borderwidth || (
22520
+ tinycolor(bgcolor).getAlpha() &&
22521
+ !tinycolor.equals(fullLayout.paper_bgcolor, bgcolor)
22522
+ )
22523
+ )) {
22524
+ // for horizontal colorbars when there is a border line or having different background color
22525
+ // hide/adjust x positioning for the first/last tick labels if they go outside the border
22526
+ var tickLabels = axLayer.selectAll('text');
22527
+ var numTicks = tickLabels[0].length;
22528
+
22529
+ var border = g.select('.' + cn.cbbg).node();
22530
+ var oBb = Drawing.bBox(border);
22531
+ var oTr = Drawing.getTranslate(g);
22532
+
22533
+ var TEXTPAD = 2;
22534
+
22535
+ tickLabels.each(function(d, i) {
22536
+ var first = 0;
22537
+ var last = numTicks - 1;
22538
+ if(i === first || i === last) {
22539
+ var iBb = Drawing.bBox(this);
22540
+ var iTr = Drawing.getTranslate(this);
22541
+ var deltaX;
22542
+
22543
+ if(i === last) {
22544
+ var iRight = iBb.right + iTr.x;
22545
+ var oRight = oBb.right + oTr.x + vPx - borderwidth - TEXTPAD + optsX;
22546
+
22547
+ deltaX = oRight - iRight;
22548
+ if(deltaX > 0) deltaX = 0;
22549
+ } else if(i === first) {
22550
+ var iLeft = iBb.left + iTr.x;
22551
+ var oLeft = oBb.left + oTr.x + vPx + borderwidth + TEXTPAD;
22552
+
22553
+ deltaX = oLeft - iLeft;
22554
+ if(deltaX < 0) deltaX = 0;
22555
+ }
22556
+
22557
+ if(deltaX) {
22558
+ if(numTicks < 3) { // adjust position
22559
+ this.setAttribute('transform',
22560
+ 'translate(' + deltaX + ',0) ' +
22561
+ this.getAttribute('transform')
22562
+ );
22563
+ } else { // hide
22564
+ this.setAttribute('visibility', 'hidden');
22565
+ }
22566
+ }
22567
+ }
22568
+ });
22569
+ }
22336
22570
 
22337
22571
  // auto margin adjustment
22338
22572
  var marginOpts = {};
22573
+ var lFrac = FROM_TL[xanchor];
22574
+ var rFrac = FROM_BR[xanchor];
22339
22575
  var tFrac = FROM_TL[yanchor];
22340
22576
  var bFrac = FROM_BR[yanchor];
22341
- if(lenmode === 'pixels') {
22342
- marginOpts.y = optsY;
22343
- marginOpts.t = lenPx * tFrac;
22344
- marginOpts.b = lenPx * bFrac;
22345
- } else {
22346
- marginOpts.t = marginOpts.b = 0;
22347
- marginOpts.yt = optsY + len * tFrac;
22348
- marginOpts.yb = optsY - len * bFrac;
22349
- }
22350
22577
 
22351
- var lFrac = FROM_TL[xanchor];
22352
- var rFrac = FROM_BR[xanchor];
22353
- if(thicknessmode === 'pixels') {
22354
- marginOpts.x = optsX;
22355
- marginOpts.l = outerThickness * lFrac;
22356
- marginOpts.r = outerThickness * rFrac;
22357
- } else {
22358
- var extraThickness = outerThickness - thickPx;
22359
- marginOpts.l = extraThickness * lFrac;
22360
- marginOpts.r = extraThickness * rFrac;
22361
- marginOpts.xl = optsX - thickness * lFrac;
22362
- marginOpts.xr = optsX + thickness * rFrac;
22578
+ var extraThickness = outerThickness - thickPx;
22579
+ if(isVertical) {
22580
+ if(lenmode === 'pixels') {
22581
+ marginOpts.y = optsY;
22582
+ marginOpts.t = lenPx * tFrac;
22583
+ marginOpts.b = lenPx * bFrac;
22584
+ } else {
22585
+ marginOpts.t = marginOpts.b = 0;
22586
+ marginOpts.yt = optsY + len * tFrac;
22587
+ marginOpts.yb = optsY - len * bFrac;
22588
+ }
22589
+
22590
+ if(thicknessmode === 'pixels') {
22591
+ marginOpts.x = optsX;
22592
+ marginOpts.l = outerThickness * lFrac;
22593
+ marginOpts.r = outerThickness * rFrac;
22594
+ } else {
22595
+ marginOpts.l = extraThickness * lFrac;
22596
+ marginOpts.r = extraThickness * rFrac;
22597
+ marginOpts.xl = optsX - thickness * lFrac;
22598
+ marginOpts.xr = optsX + thickness * rFrac;
22599
+ }
22600
+ } else { // horizontal colorbars
22601
+ if(lenmode === 'pixels') {
22602
+ marginOpts.x = optsX;
22603
+ marginOpts.l = lenPx * lFrac;
22604
+ marginOpts.r = lenPx * rFrac;
22605
+ } else {
22606
+ marginOpts.l = marginOpts.r = 0;
22607
+ marginOpts.xl = optsX + len * lFrac;
22608
+ marginOpts.xr = optsX - len * rFrac;
22609
+ }
22610
+
22611
+ if(thicknessmode === 'pixels') {
22612
+ marginOpts.y = 1 - optsY;
22613
+ marginOpts.t = outerThickness * tFrac;
22614
+ marginOpts.b = outerThickness * bFrac;
22615
+ } else {
22616
+ marginOpts.t = extraThickness * tFrac;
22617
+ marginOpts.b = extraThickness * bFrac;
22618
+ marginOpts.yt = optsY - thickness * tFrac;
22619
+ marginOpts.yb = optsY + thickness * bFrac;
22620
+ }
22363
22621
  }
22364
22622
 
22365
22623
  Plots.autoMargin(gd, opts._id, marginOpts);
@@ -22376,6 +22634,7 @@ function drawColorBar(g, opts, gd) {
22376
22634
  }
22377
22635
 
22378
22636
  function makeEditable(g, opts, gd) {
22637
+ var isVertical = opts.orientation === 'v';
22379
22638
  var fullLayout = gd._fullLayout;
22380
22639
  var gs = fullLayout._size;
22381
22640
  var t0, xf, yf;
@@ -22390,9 +22649,13 @@ function makeEditable(g, opts, gd) {
22390
22649
  moveFn: function(dx, dy) {
22391
22650
  g.attr('transform', t0 + strTranslate(dx, dy));
22392
22651
 
22393
- xf = dragElement.align(opts._uFrac + (dx / gs.w), opts._thickFrac,
22652
+ xf = dragElement.align(
22653
+ (isVertical ? opts._uFrac : opts._vFrac) + (dx / gs.w),
22654
+ isVertical ? opts._thickFrac : opts._lenFrac,
22394
22655
  0, 1, opts.xanchor);
22395
- yf = dragElement.align(opts._vFrac - (dy / gs.h), opts._lenFrac,
22656
+ yf = dragElement.align(
22657
+ (isVertical ? opts._vFrac : (1 - opts._uFrac)) - (dy / gs.h),
22658
+ isVertical ? opts._lenFrac : opts._thickFrac,
22396
22659
  0, 1, opts.yanchor);
22397
22660
 
22398
22661
  var csr = dragElement.getCursor(xf, yf, opts.xanchor, opts.yanchor);
@@ -22469,6 +22732,8 @@ function calcLevels(gd, opts, zrange) {
22469
22732
  function mockColorBarAxis(gd, opts, zrange) {
22470
22733
  var fullLayout = gd._fullLayout;
22471
22734
 
22735
+ var isVertical = opts.orientation === 'v';
22736
+
22472
22737
  var cbAxisIn = {
22473
22738
  type: 'linear',
22474
22739
  range: zrange,
@@ -22499,17 +22764,19 @@ function mockColorBarAxis(gd, opts, zrange) {
22499
22764
  title: opts.title,
22500
22765
  showline: true,
22501
22766
  anchor: 'free',
22502
- side: 'right',
22767
+ side: isVertical ? 'right' : 'bottom',
22503
22768
  position: 1
22504
22769
  };
22505
22770
 
22771
+ var letter = isVertical ? 'y' : 'x';
22772
+
22506
22773
  var cbAxisOut = {
22507
22774
  type: 'linear',
22508
- _id: 'y' + opts._id
22775
+ _id: letter + opts._id
22509
22776
  };
22510
22777
 
22511
22778
  var axisOptions = {
22512
- letter: 'y',
22779
+ letter: letter,
22513
22780
  font: fullLayout.font,
22514
22781
  noHover: true,
22515
22782
  noTickson: true,
@@ -24971,7 +25238,7 @@ var TEXTOFFSETSIGN = {
24971
25238
  start: 1, end: -1, middle: 0, bottom: 1, top: -1
24972
25239
  };
24973
25240
 
24974
- function textPointPosition(s, textPosition, fontSize, markerRadius) {
25241
+ function textPointPosition(s, textPosition, fontSize, markerRadius, dontTouchParent) {
24975
25242
  var group = d3.select(s.node().parentNode);
24976
25243
 
24977
25244
  var v = textPosition.indexOf('top') !== -1 ?
@@ -24993,7 +25260,9 @@ function textPointPosition(s, textPosition, fontSize, markerRadius) {
24993
25260
 
24994
25261
  // fix the overall text group position
24995
25262
  s.attr('text-anchor', h);
24996
- group.attr('transform', strTranslate(dx, dy));
25263
+ if(!dontTouchParent) {
25264
+ group.attr('transform', strTranslate(dx, dy));
25265
+ }
24997
25266
  }
24998
25267
 
24999
25268
  function extracTextFontSize(d, trace) {
@@ -25063,7 +25332,8 @@ drawing.selectedTextStyle = function(s, trace) {
25063
25332
  var fontSize = extracTextFontSize(d, trace);
25064
25333
 
25065
25334
  Color.fill(tx, tc);
25066
- textPointPosition(tx, tp, fontSize, d.mrc2 || d.mrc);
25335
+ var dontTouchParent = Registry.traceIs(trace, 'bar-like');
25336
+ textPointPosition(tx, tp, fontSize, d.mrc2 || d.mrc, dontTouchParent);
25067
25337
  });
25068
25338
  };
25069
25339
 
@@ -28119,7 +28389,9 @@ function createHoverText(hoverData, opts) {
28119
28389
  orientation: 'v'
28120
28390
  }
28121
28391
  };
28122
- var mockLayoutOut = {};
28392
+ var mockLayoutOut = {
28393
+ font: font
28394
+ };
28123
28395
  legendSupplyDefaults(mockLayoutIn, mockLayoutOut, gd._fullData);
28124
28396
  var mockLegend = mockLayoutOut.legend;
28125
28397
 
@@ -28160,7 +28432,8 @@ function createHoverText(hoverData, opts) {
28160
28432
 
28161
28433
  // Draw unified hover label
28162
28434
  mockLegend._inHover = true;
28163
- mockLegend._groupTitleFont = font;
28435
+ mockLegend._groupTitleFont = hoverlabel.grouptitlefont;
28436
+
28164
28437
  legendDraw(gd, mockLegend);
28165
28438
 
28166
28439
  // Position the hover
@@ -29162,9 +29435,11 @@ var isUnifiedHover = _dereq_('./helpers').isUnifiedHover;
29162
29435
  module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts) {
29163
29436
  opts = opts || {};
29164
29437
 
29438
+ var hasLegend = contOut.legend;
29439
+
29165
29440
  function inheritFontAttr(attr) {
29166
29441
  if(!opts.font[attr]) {
29167
- opts.font[attr] = contOut.legend ? contOut.legend.font[attr] : contOut.font[attr];
29442
+ opts.font[attr] = hasLegend ? contOut.legend.font[attr] : contOut.font[attr];
29168
29443
  }
29169
29444
  }
29170
29445
 
@@ -29175,7 +29450,7 @@ module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts
29175
29450
  inheritFontAttr('family');
29176
29451
  inheritFontAttr('color');
29177
29452
 
29178
- if(contOut.legend) {
29453
+ if(hasLegend) {
29179
29454
  if(!opts.bgcolor) opts.bgcolor = Color.combine(contOut.legend.bgcolor, contOut.paper_bgcolor);
29180
29455
  if(!opts.bordercolor) opts.bordercolor = contOut.legend.bordercolor;
29181
29456
  } else {
@@ -29284,11 +29559,13 @@ function castHoverinfo(trace, fullLayout, ptNumber) {
29284
29559
 
29285
29560
  var constants = _dereq_('./constants');
29286
29561
 
29287
- var fontAttrs = _dereq_('../../plots/font_attributes')({
29562
+ var fontAttrs = _dereq_('../../plots/font_attributes');
29563
+
29564
+ var font = fontAttrs({
29288
29565
  editType: 'none',
29289
29566
  });
29290
- fontAttrs.family.dflt = constants.HOVERFONT;
29291
- fontAttrs.size.dflt = constants.HOVERFONTSIZE;
29567
+ font.family.dflt = constants.HOVERFONT;
29568
+ font.size.dflt = constants.HOVERFONTSIZE;
29292
29569
 
29293
29570
  module.exports = {
29294
29571
  clickmode: {
@@ -29344,7 +29621,10 @@ module.exports = {
29344
29621
  valType: 'color',
29345
29622
  editType: 'none',
29346
29623
  },
29347
- font: fontAttrs,
29624
+ font: font,
29625
+ grouptitlefont: fontAttrs({
29626
+ editType: 'none',
29627
+ }),
29348
29628
  align: {
29349
29629
  valType: 'enumerated',
29350
29630
  values: ['left', 'right', 'auto'],
@@ -29357,6 +29637,7 @@ module.exports = {
29357
29637
  dflt: 15,
29358
29638
  editType: 'none',
29359
29639
  },
29640
+
29360
29641
  editType: 'none'
29361
29642
  },
29362
29643
  selectdirection: {
@@ -29404,6 +29685,8 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut) {
29404
29685
  }
29405
29686
 
29406
29687
  handleHoverLabelDefaults(layoutIn, layoutOut, coerce);
29688
+
29689
+ Lib.coerceFont(coerce, 'hoverlabel.grouptitlefont', layoutOut.hoverlabel.font);
29407
29690
  };
29408
29691
 
29409
29692
  },{"../../lib":232,"./hoverlabel_defaults":140,"./hovermode_defaults":141,"./layout_attributes":143}],145:[function(_dereq_,module,exports){
@@ -30287,6 +30570,9 @@ module.exports = {
30287
30570
  font: fontAttrs({
30288
30571
  editType: 'legend',
30289
30572
  }),
30573
+ grouptitlefont: fontAttrs({
30574
+ editType: 'legend',
30575
+ }),
30290
30576
  orientation: {
30291
30577
  valType: 'enumerated',
30292
30578
  values: ['v', 'h'],
@@ -30410,6 +30696,7 @@ var Registry = _dereq_('../../registry');
30410
30696
  var Lib = _dereq_('../../lib');
30411
30697
  var Template = _dereq_('../../plot_api/plot_template');
30412
30698
 
30699
+ var plotsAttrs = _dereq_('../../plots/attributes');
30413
30700
  var attributes = _dereq_('./attributes');
30414
30701
  var basePlotLayoutAttributes = _dereq_('../../plots/layout_attributes');
30415
30702
  var helpers = _dereq_('./helpers');
@@ -30417,13 +30704,30 @@ var helpers = _dereq_('./helpers');
30417
30704
 
30418
30705
  module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
30419
30706
  var containerIn = layoutIn.legend || {};
30707
+ var containerOut = Template.newContainer(layoutOut, 'legend');
30708
+
30709
+ function coerce(attr, dflt) {
30710
+ return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
30711
+ }
30712
+
30713
+ var trace;
30714
+ var traceCoerce = function(attr, dflt) {
30715
+ var traceIn = trace._input;
30716
+ var traceOut = trace;
30717
+ return Lib.coerce(traceIn, traceOut, plotsAttrs, attr, dflt);
30718
+ };
30719
+
30720
+ var globalFont = layoutOut.font || {};
30721
+ var grouptitlefont = Lib.coerceFont(coerce, 'grouptitlefont', Lib.extendFlat({}, globalFont, {
30722
+ size: Math.round(globalFont.size * 1.1)
30723
+ }));
30420
30724
 
30421
30725
  var legendTraceCount = 0;
30422
30726
  var legendReallyHasATrace = false;
30423
30727
  var defaultOrder = 'normal';
30424
30728
 
30425
30729
  for(var i = 0; i < fullData.length; i++) {
30426
- var trace = fullData[i];
30730
+ trace = fullData[i];
30427
30731
 
30428
30732
  if(!trace.visible) continue;
30429
30733
 
@@ -30450,6 +30754,8 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
30450
30754
  legendTraceCount++;
30451
30755
  }
30452
30756
  }
30757
+
30758
+ Lib.coerceFont(traceCoerce, 'legendgrouptitle.font', grouptitlefont);
30453
30759
  }
30454
30760
 
30455
30761
  if((Registry.traceIs(trace, 'bar') && layoutOut.barmode === 'stack') ||
@@ -30468,13 +30774,10 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
30468
30774
  basePlotLayoutAttributes, 'showlegend',
30469
30775
  legendReallyHasATrace && legendTraceCount > 1);
30470
30776
 
30471
- if(showLegend === false && !containerIn.uirevision) return;
30777
+ // delete legend
30778
+ if(showLegend === false) layoutOut.legend = undefined;
30472
30779
 
30473
- var containerOut = Template.newContainer(layoutOut, 'legend');
30474
-
30475
- function coerce(attr, dflt) {
30476
- return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
30477
- }
30780
+ if(showLegend === false && !containerIn.uirevision) return;
30478
30781
 
30479
30782
  coerce('uirevision', layoutOut.uirevision);
30480
30783
 
@@ -30536,7 +30839,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
30536
30839
  }
30537
30840
  };
30538
30841
 
30539
- },{"../../lib":232,"../../plot_api/plot_template":268,"../../plots/layout_attributes":314,"../../registry":318,"./attributes":152,"./helpers":158}],155:[function(_dereq_,module,exports){
30842
+ },{"../../lib":232,"../../plot_api/plot_template":268,"../../plots/attributes":275,"../../plots/layout_attributes":314,"../../registry":318,"./attributes":152,"./helpers":158}],155:[function(_dereq_,module,exports){
30540
30843
  'use strict';
30541
30844
 
30542
30845
  var d3 = _dereq_('@plotly/d3');
@@ -38988,8 +39291,10 @@ function draw(gd, titleClass, options) {
38988
39291
 
38989
39292
  var elShouldExist = txt || editable;
38990
39293
 
39294
+ var hColorbarMoveTitle;
38991
39295
  if(!group) {
38992
39296
  group = Lib.ensureSingle(fullLayout._infolayer, 'g', 'g-' + titleClass);
39297
+ hColorbarMoveTitle = fullLayout._hColorbarMoveTitle;
38993
39298
  }
38994
39299
 
38995
39300
  var el = group.selectAll('text')
@@ -39013,13 +39318,17 @@ function draw(gd, titleClass, options) {
39013
39318
  function drawTitle(titleEl) {
39014
39319
  var transformVal;
39015
39320
 
39321
+ if(!transform && hColorbarMoveTitle) {
39322
+ transform = {};
39323
+ }
39324
+
39016
39325
  if(transform) {
39017
39326
  transformVal = '';
39018
39327
  if(transform.rotate) {
39019
39328
  transformVal += 'rotate(' + [transform.rotate, attributes.x, attributes.y] + ')';
39020
39329
  }
39021
- if(transform.offset) {
39022
- transformVal += strTranslate(0, transform.offset);
39330
+ if(transform.offset || hColorbarMoveTitle) {
39331
+ transformVal += strTranslate(0, (transform.offset || 0) - (hColorbarMoveTitle || 0));
39023
39332
  }
39024
39333
  } else {
39025
39334
  transformVal = null;
@@ -50477,7 +50786,7 @@ function cleanDeprecatedAttributeKeys(aobj) {
50477
50786
  if((key === 'title' || oldAxisTitleRegex.test(key) || colorbarRegex.test(key)) &&
50478
50787
  (typeof value === 'string' || typeof value === 'number')) {
50479
50788
  replace(key, key.replace('title', 'title.text'));
50480
- } else if(key.indexOf('titlefont') > -1) {
50789
+ } else if(key.indexOf('titlefont') > -1 && key.indexOf('grouptitlefont') === -1) {
50481
50790
  replace(key, key.replace('titlefont', 'title.font'));
50482
50791
  } else if(key.indexOf('titleposition') > -1) {
50483
50792
  replace(key, key.replace('titleposition', 'title.position'));
@@ -51154,7 +51463,8 @@ function findUIPattern(key, patternSpecs) {
51154
51463
  var spec = patternSpecs[i];
51155
51464
  var match = key.match(spec.pattern);
51156
51465
  if(match) {
51157
- return {head: match[1], attr: spec.attr};
51466
+ var head = match[1] || '';
51467
+ return {head: head, tail: key.substr(head.length + 1), attr: spec.attr};
51158
51468
  }
51159
51469
  }
51160
51470
  }
@@ -51206,26 +51516,54 @@ function valsMatch(v1, v2) {
51206
51516
 
51207
51517
  function applyUIRevisions(data, layout, oldFullData, oldFullLayout) {
51208
51518
  var layoutPreGUI = oldFullLayout._preGUI;
51209
- var key, revAttr, oldRev, newRev, match, preGUIVal, newNP, newVal;
51519
+ var key, revAttr, oldRev, newRev, match, preGUIVal, newNP, newVal, head, tail;
51210
51520
  var bothInheritAutorange = [];
51521
+ var newAutorangeIn = {};
51211
51522
  var newRangeAccepted = {};
51212
51523
  for(key in layoutPreGUI) {
51213
51524
  match = findUIPattern(key, layoutUIControlPatterns);
51214
51525
  if(match) {
51215
- revAttr = match.attr || (match.head + '.uirevision');
51526
+ head = match.head;
51527
+ tail = match.tail;
51528
+ revAttr = match.attr || (head + '.uirevision');
51216
51529
  oldRev = nestedProperty(oldFullLayout, revAttr).get();
51217
51530
  newRev = oldRev && getNewRev(revAttr, layout);
51531
+
51218
51532
  if(newRev && (newRev === oldRev)) {
51219
51533
  preGUIVal = layoutPreGUI[key];
51220
51534
  if(preGUIVal === null) preGUIVal = undefined;
51221
51535
  newNP = nestedProperty(layout, key);
51222
51536
  newVal = newNP.get();
51537
+
51223
51538
  if(valsMatch(newVal, preGUIVal)) {
51224
- if(newVal === undefined && key.substr(key.length - 9) === 'autorange') {
51225
- bothInheritAutorange.push(key.substr(0, key.length - 10));
51539
+ if(newVal === undefined && tail === 'autorange') {
51540
+ bothInheritAutorange.push(head);
51226
51541
  }
51227
51542
  newNP.set(undefinedToNull(nestedProperty(oldFullLayout, key).get()));
51228
51543
  continue;
51544
+ } else if(tail === 'autorange' || tail.substr(0, 6) === 'range[') {
51545
+ // Special case for (auto)range since we push it back into the layout
51546
+ // so all null should be treated equivalently to autorange: true with any range
51547
+ var pre0 = layoutPreGUI[head + '.range[0]'];
51548
+ var pre1 = layoutPreGUI[head + '.range[1]'];
51549
+ var preAuto = layoutPreGUI[head + '.autorange'];
51550
+ if(preAuto || (preAuto === null && pre0 === null && pre1 === null)) {
51551
+ // Only read the input layout once and stash the result,
51552
+ // so we get it before we start modifying it
51553
+ if(!(head in newAutorangeIn)) {
51554
+ var newContainer = nestedProperty(layout, head).get();
51555
+ newAutorangeIn[head] = newContainer && (
51556
+ newContainer.autorange ||
51557
+ (newContainer.autorange !== false && (
51558
+ !newContainer.range || newContainer.range.length !== 2)
51559
+ )
51560
+ );
51561
+ }
51562
+ if(newAutorangeIn[head]) {
51563
+ newNP.set(undefinedToNull(nestedProperty(oldFullLayout, key).get()));
51564
+ continue;
51565
+ }
51566
+ }
51229
51567
  }
51230
51568
  }
51231
51569
  } else {
@@ -51236,12 +51574,12 @@ function applyUIRevisions(data, layout, oldFullData, oldFullLayout) {
51236
51574
  // so remove it from _preGUI for next time.
51237
51575
  delete layoutPreGUI[key];
51238
51576
 
51239
- if(key.substr(key.length - 8, 6) === 'range[') {
51240
- newRangeAccepted[key.substr(0, key.length - 9)] = 1;
51577
+ if(match && match.tail.substr(0, 6) === 'range[') {
51578
+ newRangeAccepted[match.head] = 1;
51241
51579
  }
51242
51580
  }
51243
51581
 
51244
- // Special logic for `autorange`, since it interacts with `range`:
51582
+ // More special logic for `autorange`, since it interacts with `range`:
51245
51583
  // If the new figure's matching `range` was kept, and `autorange`
51246
51584
  // wasn't supplied explicitly in either the original or the new figure,
51247
51585
  // we shouldn't alter that - but we may just have done that, so fix it.
@@ -68316,6 +68654,9 @@ module.exports = function(opts) {
68316
68654
  // TODO - that's uber hacky... better solution?
68317
68655
  };
68318
68656
 
68657
+ if(opts.autoSize) attrs.size.dflt = 'auto';
68658
+ if(opts.autoColor) attrs.color.dflt = 'auto';
68659
+
68319
68660
  if(opts.arrayOk) {
68320
68661
  attrs.family.arrayOk = true;
68321
68662
  attrs.size.arrayOk = true;
@@ -68675,6 +69016,7 @@ module.exports = {
68675
69016
  valType: 'boolean',
68676
69017
  editType: 'legend',
68677
69018
  },
69019
+
68678
69020
  colorway: {
68679
69021
  valType: 'colorlist',
68680
69022
  dflt: colorAttrs.defaults,
@@ -70087,13 +70429,7 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac
70087
70429
  );
70088
70430
 
70089
70431
  coerce('legendgroup');
70090
- var titleText = coerce('legendgrouptitle.text');
70091
- if(titleText) {
70092
- Lib.coerceFont(coerce, 'legendgrouptitle.font', Lib.extendFlat({}, layout.font, {
70093
- size: Math.round(layout.font.size * 1.1) // default to larger font size
70094
- }));
70095
- }
70096
-
70432
+ coerce('legendgrouptitle.text');
70097
70433
  coerce('legendrank');
70098
70434
 
70099
70435
  traceOut._dfltShowLegend = true;
@@ -70241,16 +70577,14 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut, formatObj) {
70241
70577
 
70242
70578
  coerce('autotypenumbers');
70243
70579
 
70244
- var globalFont = Lib.coerceFont(coerce, 'font');
70245
-
70246
- coerce('title.text', layoutOut._dfltTitle.plot);
70580
+ var font = Lib.coerceFont(coerce, 'font');
70581
+ var fontSize = font.size;
70247
70582
 
70248
- Lib.coerceFont(coerce, 'title.font', {
70249
- family: globalFont.family,
70250
- size: Math.round(globalFont.size * 1.4),
70251
- color: globalFont.color
70252
- });
70583
+ Lib.coerceFont(coerce, 'title.font', Lib.extendFlat({}, font, {
70584
+ size: Math.round(fontSize * 1.4)
70585
+ }));
70253
70586
 
70587
+ coerce('title.text', layoutOut._dfltTitle.plot);
70254
70588
  coerce('title.xref');
70255
70589
  coerce('title.yref');
70256
70590
  coerce('title.x');
@@ -75587,7 +75921,7 @@ function appendBarText(gd, plotinfo, bar, cd, i, x0, x1, y0, y1, opts, makeOnCom
75587
75921
  }
75588
75922
 
75589
75923
  transform.fontSize = font.size;
75590
- recordMinTextSize(trace.type, transform, fullLayout);
75924
+ recordMinTextSize(trace.type === 'histogram' ? 'bar' : trace.type, transform, fullLayout);
75591
75925
  calcBar.transform = transform;
75592
75926
 
75593
75927
  transition(textSelection, fullLayout, opts, makeOnCompleteCallback)
@@ -76655,7 +76989,6 @@ function calc(gd, trace) {
76655
76989
  v = vals[i];
76656
76990
  if(!isNumeric(v)) continue;
76657
76991
  v = +v;
76658
- if(v < 0) continue;
76659
76992
  } else v = 1;
76660
76993
 
76661
76994
  label = labels[i];
@@ -76692,6 +77025,9 @@ function calc(gd, trace) {
76692
77025
  }
76693
77026
  }
76694
77027
 
77028
+ // Drop aggregate sums of value 0 or less
77029
+ cd = cd.filter(function(elem) { return elem.v >= 0; });
77030
+
76695
77031
  var shouldSort = (trace.type === 'funnelarea') ? isAggregated : trace.sort;
76696
77032
  if(shouldSort) cd.sort(function(a, b) { return b.v - a.v; });
76697
77033
 
@@ -82288,7 +82624,7 @@ function getSortFunc(opts, d2c) {
82288
82624
  'use strict';
82289
82625
 
82290
82626
  // package version injected by `npm run preprocess`
82291
- exports.version = '2.6.3';
82627
+ exports.version = '2.8.1';
82292
82628
 
82293
82629
  },{}]},{},[8])(8)
82294
82630
  });