plotly.js 2.7.0 → 2.8.3

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 (54) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +3 -3
  3. package/dist/README.md +26 -26
  4. package/dist/plot-schema.json +898 -407
  5. package/dist/plotly-basic.js +497 -186
  6. package/dist/plotly-basic.min.js +4 -4
  7. package/dist/plotly-cartesian.js +907 -329
  8. package/dist/plotly-cartesian.min.js +3 -3
  9. package/dist/plotly-finance.js +500 -188
  10. package/dist/plotly-finance.min.js +4 -4
  11. package/dist/plotly-geo-assets.js +2 -2
  12. package/dist/plotly-geo.js +486 -184
  13. package/dist/plotly-geo.min.js +4 -4
  14. package/dist/plotly-gl2d.js +505 -187
  15. package/dist/plotly-gl2d.min.js +2 -2
  16. package/dist/plotly-gl3d.js +486 -184
  17. package/dist/plotly-gl3d.min.js +2 -2
  18. package/dist/plotly-mapbox.js +486 -184
  19. package/dist/plotly-mapbox.min.js +2 -2
  20. package/dist/plotly-strict.js +1125 -547
  21. package/dist/plotly-strict.min.js +3 -3
  22. package/dist/plotly-with-meta.js +1214 -609
  23. package/dist/plotly.js +1179 -601
  24. package/dist/plotly.min.js +10 -10
  25. package/package.json +4 -4
  26. package/src/components/colorbar/attributes.js +29 -20
  27. package/src/components/colorbar/defaults.js +30 -8
  28. package/src/components/colorbar/draw.js +374 -128
  29. package/src/components/fx/hover.js +5 -2
  30. package/src/components/fx/hoverlabel_defaults.js +4 -2
  31. package/src/components/fx/layout_attributes.js +14 -4
  32. package/src/components/fx/layout_defaults.js +2 -0
  33. package/src/components/legend/attributes.js +7 -0
  34. package/src/components/legend/defaults.js +24 -7
  35. package/src/components/titles/index.js +8 -2
  36. package/src/plot_api/plot_api.js +1 -1
  37. package/src/plots/font_attributes.js +3 -0
  38. package/src/plots/layout_attributes.js +1 -0
  39. package/src/plots/plots.js +7 -15
  40. package/src/traces/bar/plot.js +8 -1
  41. package/src/traces/contour/attributes.js +12 -0
  42. package/src/traces/contour/defaults.js +9 -1
  43. package/src/traces/heatmap/attributes.js +16 -0
  44. package/src/traces/heatmap/defaults.js +2 -0
  45. package/src/traces/heatmap/label_defaults.js +13 -0
  46. package/src/traces/heatmap/plot.js +205 -4
  47. package/src/traces/histogram/calc.js +3 -2
  48. package/src/traces/histogram2d/attributes.js +8 -0
  49. package/src/traces/histogram2d/defaults.js +4 -0
  50. package/src/traces/histogram2dcontour/attributes.js +3 -1
  51. package/src/traces/histogram2dcontour/defaults.js +8 -1
  52. package/src/traces/pie/calc.js +3 -1
  53. package/src/version.js +1 -1
  54. package/tasks/test_mock.js +1 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * plotly.js (basic) v2.7.0
2
+ * plotly.js (basic) v2.8.3
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;
22038
22078
 
22039
- if(['top', 'bottom'].indexOf(titleSide) !== -1) {
22079
+ if(isVertical && topOrBottom) {
22040
22080
  ax.title.side = titleSide;
22041
- ax.titlex = optsX + xpadFrac;
22042
- ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
22081
+ ax.titlex = optsX + xpad / gs.w;
22082
+ ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypad / gs.h : ypad / gs.h);
22083
+ }
22084
+
22085
+ if(!isVertical && !topOrBottom) {
22086
+ ax.title.side = titleSide;
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;
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;
22120
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,
@@ -28122,7 +28389,9 @@ function createHoverText(hoverData, opts) {
28122
28389
  orientation: 'v'
28123
28390
  }
28124
28391
  };
28125
- var mockLayoutOut = {};
28392
+ var mockLayoutOut = {
28393
+ font: font
28394
+ };
28126
28395
  legendSupplyDefaults(mockLayoutIn, mockLayoutOut, gd._fullData);
28127
28396
  var mockLegend = mockLayoutOut.legend;
28128
28397
 
@@ -28163,7 +28432,8 @@ function createHoverText(hoverData, opts) {
28163
28432
 
28164
28433
  // Draw unified hover label
28165
28434
  mockLegend._inHover = true;
28166
- mockLegend._groupTitleFont = font;
28435
+ mockLegend._groupTitleFont = hoverlabel.grouptitlefont;
28436
+
28167
28437
  legendDraw(gd, mockLegend);
28168
28438
 
28169
28439
  // Position the hover
@@ -29165,9 +29435,11 @@ var isUnifiedHover = _dereq_('./helpers').isUnifiedHover;
29165
29435
  module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts) {
29166
29436
  opts = opts || {};
29167
29437
 
29438
+ var hasLegend = contOut.legend;
29439
+
29168
29440
  function inheritFontAttr(attr) {
29169
29441
  if(!opts.font[attr]) {
29170
- opts.font[attr] = contOut.legend ? contOut.legend.font[attr] : contOut.font[attr];
29442
+ opts.font[attr] = hasLegend ? contOut.legend.font[attr] : contOut.font[attr];
29171
29443
  }
29172
29444
  }
29173
29445
 
@@ -29178,7 +29450,7 @@ module.exports = function handleHoverLabelDefaults(contIn, contOut, coerce, opts
29178
29450
  inheritFontAttr('family');
29179
29451
  inheritFontAttr('color');
29180
29452
 
29181
- if(contOut.legend) {
29453
+ if(hasLegend) {
29182
29454
  if(!opts.bgcolor) opts.bgcolor = Color.combine(contOut.legend.bgcolor, contOut.paper_bgcolor);
29183
29455
  if(!opts.bordercolor) opts.bordercolor = contOut.legend.bordercolor;
29184
29456
  } else {
@@ -29287,11 +29559,13 @@ function castHoverinfo(trace, fullLayout, ptNumber) {
29287
29559
 
29288
29560
  var constants = _dereq_('./constants');
29289
29561
 
29290
- var fontAttrs = _dereq_('../../plots/font_attributes')({
29562
+ var fontAttrs = _dereq_('../../plots/font_attributes');
29563
+
29564
+ var font = fontAttrs({
29291
29565
  editType: 'none',
29292
29566
  });
29293
- fontAttrs.family.dflt = constants.HOVERFONT;
29294
- fontAttrs.size.dflt = constants.HOVERFONTSIZE;
29567
+ font.family.dflt = constants.HOVERFONT;
29568
+ font.size.dflt = constants.HOVERFONTSIZE;
29295
29569
 
29296
29570
  module.exports = {
29297
29571
  clickmode: {
@@ -29347,7 +29621,10 @@ module.exports = {
29347
29621
  valType: 'color',
29348
29622
  editType: 'none',
29349
29623
  },
29350
- font: fontAttrs,
29624
+ font: font,
29625
+ grouptitlefont: fontAttrs({
29626
+ editType: 'none',
29627
+ }),
29351
29628
  align: {
29352
29629
  valType: 'enumerated',
29353
29630
  values: ['left', 'right', 'auto'],
@@ -29360,6 +29637,7 @@ module.exports = {
29360
29637
  dflt: 15,
29361
29638
  editType: 'none',
29362
29639
  },
29640
+
29363
29641
  editType: 'none'
29364
29642
  },
29365
29643
  selectdirection: {
@@ -29407,6 +29685,8 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut) {
29407
29685
  }
29408
29686
 
29409
29687
  handleHoverLabelDefaults(layoutIn, layoutOut, coerce);
29688
+
29689
+ Lib.coerceFont(coerce, 'hoverlabel.grouptitlefont', layoutOut.hoverlabel.font);
29410
29690
  };
29411
29691
 
29412
29692
  },{"../../lib":232,"./hoverlabel_defaults":140,"./hovermode_defaults":141,"./layout_attributes":143}],145:[function(_dereq_,module,exports){
@@ -30290,6 +30570,9 @@ module.exports = {
30290
30570
  font: fontAttrs({
30291
30571
  editType: 'legend',
30292
30572
  }),
30573
+ grouptitlefont: fontAttrs({
30574
+ editType: 'legend',
30575
+ }),
30293
30576
  orientation: {
30294
30577
  valType: 'enumerated',
30295
30578
  values: ['v', 'h'],
@@ -30413,6 +30696,7 @@ var Registry = _dereq_('../../registry');
30413
30696
  var Lib = _dereq_('../../lib');
30414
30697
  var Template = _dereq_('../../plot_api/plot_template');
30415
30698
 
30699
+ var plotsAttrs = _dereq_('../../plots/attributes');
30416
30700
  var attributes = _dereq_('./attributes');
30417
30701
  var basePlotLayoutAttributes = _dereq_('../../plots/layout_attributes');
30418
30702
  var helpers = _dereq_('./helpers');
@@ -30420,13 +30704,30 @@ var helpers = _dereq_('./helpers');
30420
30704
 
30421
30705
  module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
30422
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
+ }));
30423
30724
 
30424
30725
  var legendTraceCount = 0;
30425
30726
  var legendReallyHasATrace = false;
30426
30727
  var defaultOrder = 'normal';
30427
30728
 
30428
30729
  for(var i = 0; i < fullData.length; i++) {
30429
- var trace = fullData[i];
30730
+ trace = fullData[i];
30430
30731
 
30431
30732
  if(!trace.visible) continue;
30432
30733
 
@@ -30453,6 +30754,8 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
30453
30754
  legendTraceCount++;
30454
30755
  }
30455
30756
  }
30757
+
30758
+ Lib.coerceFont(traceCoerce, 'legendgrouptitle.font', grouptitlefont);
30456
30759
  }
30457
30760
 
30458
30761
  if((Registry.traceIs(trace, 'bar') && layoutOut.barmode === 'stack') ||
@@ -30471,13 +30774,10 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
30471
30774
  basePlotLayoutAttributes, 'showlegend',
30472
30775
  legendReallyHasATrace && legendTraceCount > 1);
30473
30776
 
30474
- if(showLegend === false && !containerIn.uirevision) return;
30475
-
30476
- var containerOut = Template.newContainer(layoutOut, 'legend');
30777
+ // delete legend
30778
+ if(showLegend === false) layoutOut.legend = undefined;
30477
30779
 
30478
- function coerce(attr, dflt) {
30479
- return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);
30480
- }
30780
+ if(showLegend === false && !containerIn.uirevision) return;
30481
30781
 
30482
30782
  coerce('uirevision', layoutOut.uirevision);
30483
30783
 
@@ -30539,7 +30839,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
30539
30839
  }
30540
30840
  };
30541
30841
 
30542
- },{"../../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){
30543
30843
  'use strict';
30544
30844
 
30545
30845
  var d3 = _dereq_('@plotly/d3');
@@ -38991,8 +39291,10 @@ function draw(gd, titleClass, options) {
38991
39291
 
38992
39292
  var elShouldExist = txt || editable;
38993
39293
 
39294
+ var hColorbarMoveTitle;
38994
39295
  if(!group) {
38995
39296
  group = Lib.ensureSingle(fullLayout._infolayer, 'g', 'g-' + titleClass);
39297
+ hColorbarMoveTitle = fullLayout._hColorbarMoveTitle;
38996
39298
  }
38997
39299
 
38998
39300
  var el = group.selectAll('text')
@@ -39016,13 +39318,17 @@ function draw(gd, titleClass, options) {
39016
39318
  function drawTitle(titleEl) {
39017
39319
  var transformVal;
39018
39320
 
39321
+ if(!transform && hColorbarMoveTitle) {
39322
+ transform = {};
39323
+ }
39324
+
39019
39325
  if(transform) {
39020
39326
  transformVal = '';
39021
39327
  if(transform.rotate) {
39022
39328
  transformVal += 'rotate(' + [transform.rotate, attributes.x, attributes.y] + ')';
39023
39329
  }
39024
- if(transform.offset) {
39025
- transformVal += strTranslate(0, transform.offset);
39330
+ if(transform.offset || hColorbarMoveTitle) {
39331
+ transformVal += strTranslate(0, (transform.offset || 0) - (hColorbarMoveTitle || 0));
39026
39332
  }
39027
39333
  } else {
39028
39334
  transformVal = null;
@@ -50480,7 +50786,7 @@ function cleanDeprecatedAttributeKeys(aobj) {
50480
50786
  if((key === 'title' || oldAxisTitleRegex.test(key) || colorbarRegex.test(key)) &&
50481
50787
  (typeof value === 'string' || typeof value === 'number')) {
50482
50788
  replace(key, key.replace('title', 'title.text'));
50483
- } else if(key.indexOf('titlefont') > -1) {
50789
+ } else if(key.indexOf('titlefont') > -1 && key.indexOf('grouptitlefont') === -1) {
50484
50790
  replace(key, key.replace('titlefont', 'title.font'));
50485
50791
  } else if(key.indexOf('titleposition') > -1) {
50486
50792
  replace(key, key.replace('titleposition', 'title.position'));
@@ -68348,6 +68654,9 @@ module.exports = function(opts) {
68348
68654
  // TODO - that's uber hacky... better solution?
68349
68655
  };
68350
68656
 
68657
+ if(opts.autoSize) attrs.size.dflt = 'auto';
68658
+ if(opts.autoColor) attrs.color.dflt = 'auto';
68659
+
68351
68660
  if(opts.arrayOk) {
68352
68661
  attrs.family.arrayOk = true;
68353
68662
  attrs.size.arrayOk = true;
@@ -68707,6 +69016,7 @@ module.exports = {
68707
69016
  valType: 'boolean',
68708
69017
  editType: 'legend',
68709
69018
  },
69019
+
68710
69020
  colorway: {
68711
69021
  valType: 'colorlist',
68712
69022
  dflt: colorAttrs.defaults,
@@ -70119,13 +70429,7 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac
70119
70429
  );
70120
70430
 
70121
70431
  coerce('legendgroup');
70122
- var titleText = coerce('legendgrouptitle.text');
70123
- if(titleText) {
70124
- Lib.coerceFont(coerce, 'legendgrouptitle.font', Lib.extendFlat({}, layout.font, {
70125
- size: Math.round(layout.font.size * 1.1) // default to larger font size
70126
- }));
70127
- }
70128
-
70432
+ coerce('legendgrouptitle.text');
70129
70433
  coerce('legendrank');
70130
70434
 
70131
70435
  traceOut._dfltShowLegend = true;
@@ -70273,16 +70577,14 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut, formatObj) {
70273
70577
 
70274
70578
  coerce('autotypenumbers');
70275
70579
 
70276
- var globalFont = Lib.coerceFont(coerce, 'font');
70277
-
70278
- coerce('title.text', layoutOut._dfltTitle.plot);
70580
+ var font = Lib.coerceFont(coerce, 'font');
70581
+ var fontSize = font.size;
70279
70582
 
70280
- Lib.coerceFont(coerce, 'title.font', {
70281
- family: globalFont.family,
70282
- size: Math.round(globalFont.size * 1.4),
70283
- color: globalFont.color
70284
- });
70583
+ Lib.coerceFont(coerce, 'title.font', Lib.extendFlat({}, font, {
70584
+ size: Math.round(fontSize * 1.4)
70585
+ }));
70285
70586
 
70587
+ coerce('title.text', layoutOut._dfltTitle.plot);
70286
70588
  coerce('title.xref');
70287
70589
  coerce('title.yref');
70288
70590
  coerce('title.x');
@@ -75820,12 +76122,14 @@ function calcTexttemplate(fullLayout, cd, index, xa, ya) {
75820
76122
  var trace = cd[0].trace;
75821
76123
  var texttemplate = Lib.castOption(trace, index, 'texttemplate');
75822
76124
  if(!texttemplate) return '';
76125
+ var isHistogram = (trace.type === 'histogram');
75823
76126
  var isWaterfall = (trace.type === 'waterfall');
75824
76127
  var isFunnel = (trace.type === 'funnel');
76128
+ var isHorizontal = trace.orientation === 'h';
75825
76129
 
75826
76130
  var pLetter, pAxis;
75827
76131
  var vLetter, vAxis;
75828
- if(trace.orientation === 'h') {
76132
+ if(isHorizontal) {
75829
76133
  pLetter = 'y';
75830
76134
  pAxis = ya;
75831
76135
  vLetter = 'x';
@@ -75860,6 +76164,11 @@ function calcTexttemplate(fullLayout, cd, index, xa, ya) {
75860
76164
  var pt = {};
75861
76165
  appendArrayPointValue(pt, trace, cdi.i);
75862
76166
 
76167
+ if(isHistogram || pt.x === undefined) pt.x = isHorizontal ? obj.value : obj.label;
76168
+ if(isHistogram || pt.y === undefined) pt.y = isHorizontal ? obj.label : obj.value;
76169
+ if(isHistogram || pt.xLabel === undefined) pt.xLabel = isHorizontal ? obj.valueLabel : obj.labelLabel;
76170
+ if(isHistogram || pt.yLabel === undefined) pt.yLabel = isHorizontal ? obj.labelLabel : obj.valueLabel;
76171
+
75863
76172
  if(isWaterfall) {
75864
76173
  obj.delta = +cdi.rawS || cdi.s;
75865
76174
  obj.deltaLabel = formatNumber(obj.delta);
@@ -76687,7 +76996,6 @@ function calc(gd, trace) {
76687
76996
  v = vals[i];
76688
76997
  if(!isNumeric(v)) continue;
76689
76998
  v = +v;
76690
- if(v < 0) continue;
76691
76999
  } else v = 1;
76692
77000
 
76693
77001
  label = labels[i];
@@ -76724,6 +77032,9 @@ function calc(gd, trace) {
76724
77032
  }
76725
77033
  }
76726
77034
 
77035
+ // Drop aggregate sums of value 0 or less
77036
+ cd = cd.filter(function(elem) { return elem.v >= 0; });
77037
+
76727
77038
  var shouldSort = (trace.type === 'funnelarea') ? isAggregated : trace.sort;
76728
77039
  if(shouldSort) cd.sort(function(a, b) { return b.v - a.v; });
76729
77040
 
@@ -82320,7 +82631,7 @@ function getSortFunc(opts, d2c) {
82320
82631
  'use strict';
82321
82632
 
82322
82633
  // package version injected by `npm run preprocess`
82323
- exports.version = '2.7.0';
82634
+ exports.version = '2.8.3';
82324
82635
 
82325
82636
  },{}]},{},[8])(8)
82326
82637
  });