plotly.js 1.52.1 → 1.52.2

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 (43) hide show
  1. package/.fossa.yml +58 -0
  2. package/.ignore +3 -0
  3. package/CHANGELOG.md +21 -0
  4. package/dist/README.md +25 -25
  5. package/dist/plot-schema.json +8 -8
  6. package/dist/plotly-basic.js +187 -54
  7. package/dist/plotly-basic.min.js +2 -2
  8. package/dist/plotly-cartesian.js +187 -54
  9. package/dist/plotly-cartesian.min.js +2 -2
  10. package/dist/plotly-finance.js +187 -54
  11. package/dist/plotly-finance.min.js +2 -2
  12. package/dist/plotly-geo-assets.js +2 -2
  13. package/dist/plotly-geo.js +168 -49
  14. package/dist/plotly-geo.min.js +2 -2
  15. package/dist/plotly-gl2d.js +173 -51
  16. package/dist/plotly-gl2d.min.js +2 -2
  17. package/dist/plotly-gl3d.js +668 -449
  18. package/dist/plotly-gl3d.min.js +2 -2
  19. package/dist/plotly-mapbox.js +170 -50
  20. package/dist/plotly-mapbox.min.js +2 -2
  21. package/dist/plotly-with-meta.js +823 -533
  22. package/dist/plotly.js +814 -525
  23. package/dist/plotly.min.js +2 -2
  24. package/package.json +24 -23
  25. package/src/assets/geo_assets.js +1 -1
  26. package/src/components/annotations/attributes.js +1 -1
  27. package/src/core.js +1 -1
  28. package/src/lib/index.js +6 -3
  29. package/src/plot_api/subroutines.js +6 -0
  30. package/src/plot_api/validate.js +4 -3
  31. package/src/plots/cartesian/axes.js +6 -2
  32. package/src/plots/cartesian/constants.js +1 -2
  33. package/src/plots/cartesian/layout_defaults.js +112 -27
  34. package/src/plots/gl3d/scene.js +361 -323
  35. package/src/plots/layout_attributes.js +2 -2
  36. package/src/plots/mapbox/layers.js +2 -1
  37. package/src/plots/plots.js +30 -9
  38. package/src/traces/bar/hover.js +6 -1
  39. package/src/traces/bar/plot.js +13 -4
  40. package/src/traces/mesh3d/convert.js +9 -5
  41. package/src/traces/pie/attributes.js +7 -6
  42. package/src/traces/treemap/plot.js +2 -0
  43. package/tasks/test_syntax.js +1 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * plotly.js (basic) v1.52.1
2
+ * plotly.js (basic) v1.52.2
3
3
  * Copyright 2012-2020, Plotly, Inc.
4
4
  * All rights reserved.
5
5
  * Licensed under the MIT license
@@ -34317,7 +34317,7 @@ exports.svgAttrs = {
34317
34317
  'use strict';
34318
34318
 
34319
34319
  // package version injected by `npm run preprocess`
34320
- exports.version = '1.52.1';
34320
+ exports.version = '1.52.2';
34321
34321
 
34322
34322
  // inject promise polyfill
34323
34323
  _dereq_('es6-promise').polyfill();
@@ -37904,11 +37904,14 @@ lib.templateString = function(string, obj) {
37904
37904
  var getterCache = {};
37905
37905
 
37906
37906
  return string.replace(lib.TEMPLATE_STRING_REGEX, function(dummy, key) {
37907
+ var v;
37907
37908
  if(SIMPLE_PROPERTY_REGEX.test(key)) {
37908
- return obj[key] || '';
37909
+ v = obj[key];
37910
+ } else {
37911
+ getterCache[key] = getterCache[key] || lib.nestedProperty(obj, key).get;
37912
+ v = getterCache[key]();
37909
37913
  }
37910
- getterCache[key] = getterCache[key] || lib.nestedProperty(obj, key).get;
37911
- return getterCache[key]() || '';
37914
+ return lib.isValidTextValue(v) ? v : '';
37912
37915
  });
37913
37916
  };
37914
37917
 
@@ -48094,6 +48097,7 @@ exports.doAutoRangeAndConstraints = function(gd) {
48094
48097
  var fullLayout = gd._fullLayout;
48095
48098
  var axList = Axes.list(gd, '', true);
48096
48099
  var matchGroups = fullLayout._axisMatchGroups || [];
48100
+ var axLookup = {};
48097
48101
  var ax;
48098
48102
  var axRng;
48099
48103
 
@@ -48101,6 +48105,7 @@ exports.doAutoRangeAndConstraints = function(gd) {
48101
48105
  ax = axList[i];
48102
48106
  cleanAxisConstraints(gd, ax);
48103
48107
  doAutoRange(gd, ax);
48108
+ axLookup[ax._id] = 1;
48104
48109
  }
48105
48110
 
48106
48111
  enforceAxisConstraints(gd);
@@ -48113,6 +48118,10 @@ exports.doAutoRangeAndConstraints = function(gd) {
48113
48118
 
48114
48119
  for(id in group) {
48115
48120
  ax = Axes.getFromId(gd, id);
48121
+
48122
+ // skip over 'missing' axes which do not pass through doAutoRange
48123
+ if(!axLookup[ax._id]) continue;
48124
+ // if one axis has autorange false, we're done
48116
48125
  if(ax.autorange === false) continue groupLoop;
48117
48126
 
48118
48127
  axRng = Lib.simpleMap(ax.range, ax.r2l);
@@ -48990,13 +48999,14 @@ function crawl(objIn, objOut, schema, list, base, path) {
48990
48999
  var valOut = objOut[k];
48991
49000
 
48992
49001
  var nestedSchema = getNestedSchema(schema, k);
48993
- var isInfoArray = (nestedSchema || {}).valType === 'info_array';
48994
- var isColorscale = (nestedSchema || {}).valType === 'colorscale';
49002
+ var nestedValType = (nestedSchema || {}).valType;
49003
+ var isInfoArray = nestedValType === 'info_array';
49004
+ var isColorscale = nestedValType === 'colorscale';
48995
49005
  var items = (nestedSchema || {}).items;
48996
49006
 
48997
49007
  if(!isInSchema(schema, k)) {
48998
49008
  list.push(format('schema', base, p));
48999
- } else if(isPlainObject(valIn) && isPlainObject(valOut)) {
49009
+ } else if(isPlainObject(valIn) && isPlainObject(valOut) && nestedValType !== 'any') {
49000
49010
  crawl(valIn, valOut, nestedSchema, list, base, p);
49001
49011
  } else if(isInfoArray && isArray(valIn)) {
49002
49012
  if(valIn.length > valOut.length) {
@@ -51801,10 +51811,14 @@ axes.drawOne = function(gd, ax, opts) {
51801
51811
  var axId = ax._id;
51802
51812
  var axLetter = axId.charAt(0);
51803
51813
  var counterLetter = axes.counterLetter(axId);
51804
- var mainLinePosition = ax._mainLinePosition;
51805
- var mainMirrorPosition = ax._mainMirrorPosition;
51806
51814
  var mainPlotinfo = fullLayout._plots[ax._mainSubplot];
51815
+
51816
+ // this happens when updating matched group with 'missing' axes
51817
+ if(!mainPlotinfo) return;
51818
+
51807
51819
  var mainAxLayer = mainPlotinfo[axLetter + 'axislayer'];
51820
+ var mainLinePosition = ax._mainLinePosition;
51821
+ var mainMirrorPosition = ax._mainMirrorPosition;
51808
51822
 
51809
51823
  var vals = ax._vals = axes.calcTicks(ax);
51810
51824
 
@@ -53763,11 +53777,10 @@ exports.tick0 = function(tick0, axType, calendar, dtick) {
53763
53777
  */
53764
53778
 
53765
53779
  'use strict';
53766
- var counterRegex = _dereq_('../../lib/regex').counter;
53767
53780
 
53781
+ var counterRegex = _dereq_('../../lib/regex').counter;
53768
53782
 
53769
53783
  module.exports = {
53770
-
53771
53784
  idRegex: {
53772
53785
  x: counterRegex('x'),
53773
53786
  y: counterRegex('y')
@@ -56957,6 +56970,8 @@ var axisIds = _dereq_('./axis_ids');
56957
56970
  var id2name = axisIds.id2name;
56958
56971
  var name2id = axisIds.name2id;
56959
56972
 
56973
+ var AX_ID_PATTERN = _dereq_('./constants').AX_ID_PATTERN;
56974
+
56960
56975
  var Registry = _dereq_('../../registry');
56961
56976
  var traceIs = Registry.traceIs;
56962
56977
  var getComponentMethod = Registry.getComponentMethod;
@@ -57066,7 +57081,28 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57066
57081
 
57067
57082
  var bgColor = Color.combine(plotBgColor, layoutOut.paper_bgcolor);
57068
57083
 
57069
- var axName, axLetter, axLayoutIn, axLayoutOut;
57084
+ // name of single axis (e.g. 'xaxis', 'yaxis2')
57085
+ var axName;
57086
+ // id of single axis (e.g. 'y', 'x5')
57087
+ var axId;
57088
+ // 'x' or 'y'
57089
+ var axLetter;
57090
+ // input layout axis container
57091
+ var axLayoutIn;
57092
+ // full layout axis container
57093
+ var axLayoutOut;
57094
+
57095
+ function newAxLayoutOut() {
57096
+ var traces = ax2traces[axName] || [];
57097
+ axLayoutOut._traceIndices = traces.map(function(t) { return t._expandedIndex; });
57098
+ axLayoutOut._annIndices = [];
57099
+ axLayoutOut._shapeIndices = [];
57100
+ axLayoutOut._imgIndices = [];
57101
+ axLayoutOut._subplotsWith = [];
57102
+ axLayoutOut._counterAxes = [];
57103
+ axLayoutOut._name = axLayoutOut._attr = axName;
57104
+ axLayoutOut._id = axId;
57105
+ }
57070
57106
 
57071
57107
  function coerce(attr, dflt) {
57072
57108
  return Lib.coerce(axLayoutIn, axLayoutOut, layoutAttributes, attr, dflt);
@@ -57080,9 +57116,6 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57080
57116
  return (axLetter === 'x') ? yIds : xIds;
57081
57117
  }
57082
57118
 
57083
- var counterAxes = {x: getCounterAxes('x'), y: getCounterAxes('y')};
57084
- var allAxisIds = counterAxes.x.concat(counterAxes.y);
57085
-
57086
57119
  function getOverlayableAxes(axLetter, axName) {
57087
57120
  var list = (axLetter === 'x') ? xNames : yNames;
57088
57121
  var out = [];
@@ -57098,9 +57131,30 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57098
57131
  return out;
57099
57132
  }
57100
57133
 
57134
+ // list of available counter axis names
57135
+ var counterAxes = {x: getCounterAxes('x'), y: getCounterAxes('y')};
57136
+ // list of all x AND y axis ids
57137
+ var allAxisIds = counterAxes.x.concat(counterAxes.y);
57138
+ // lookup and list of axis ids that axes in axNames have a reference to,
57139
+ // even though they are missing from allAxisIds
57140
+ var missingMatchedAxisIdsLookup = {};
57141
+ var missingMatchedAxisIds = [];
57142
+
57143
+ // fill in 'missing' axis lookup when an axis is set to match an axis
57144
+ // not part of the allAxisIds list, save axis type so that we can propagate
57145
+ // it to the missing axes
57146
+ function addMissingMatchedAxis() {
57147
+ var matchesIn = axLayoutIn.matches;
57148
+ if(AX_ID_PATTERN.test(matchesIn) && allAxisIds.indexOf(matchesIn) === -1) {
57149
+ missingMatchedAxisIdsLookup[matchesIn] = axLayoutIn.type;
57150
+ missingMatchedAxisIds = Object.keys(missingMatchedAxisIdsLookup);
57151
+ }
57152
+ }
57153
+
57101
57154
  // first pass creates the containers, determines types, and handles most of the settings
57102
57155
  for(i = 0; i < axNames.length; i++) {
57103
57156
  axName = axNames[i];
57157
+ axId = name2id(axName);
57104
57158
  axLetter = axName.charAt(0);
57105
57159
 
57106
57160
  if(!Lib.isPlainObject(layoutIn[axName])) {
@@ -57109,20 +57163,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57109
57163
 
57110
57164
  axLayoutIn = layoutIn[axName];
57111
57165
  axLayoutOut = Template.newContainer(layoutOut, axName, axLetter + 'axis');
57112
-
57113
- var traces = ax2traces[axName] || [];
57114
- axLayoutOut._traceIndices = traces.map(function(t) { return t._expandedIndex; });
57115
- axLayoutOut._annIndices = [];
57116
- axLayoutOut._shapeIndices = [];
57117
- axLayoutOut._imgIndices = [];
57118
- axLayoutOut._subplotsWith = [];
57119
- axLayoutOut._counterAxes = [];
57120
-
57121
- // set up some private properties
57122
- axLayoutOut._name = axLayoutOut._attr = axName;
57123
- var id = axLayoutOut._id = name2id(axName);
57124
-
57125
- var overlayableAxes = getOverlayableAxes(axLetter, axName);
57166
+ newAxLayoutOut();
57126
57167
 
57127
57168
  var visibleDflt =
57128
57169
  (axLetter === 'x' && !xaMustDisplay[axName] && xaMayHide[axName]) ||
@@ -57140,13 +57181,13 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57140
57181
  font: layoutOut.font,
57141
57182
  outerTicks: outerTicks[axName],
57142
57183
  showGrid: !noGrids[axName],
57143
- data: traces,
57184
+ data: ax2traces[axName] || [],
57144
57185
  bgColor: bgColor,
57145
57186
  calendar: layoutOut.calendar,
57146
57187
  automargin: true,
57147
57188
  visibleDflt: visibleDflt,
57148
57189
  reverseDflt: reverseDflt,
57149
- splomStash: ((layoutOut._splomAxes || {})[axLetter] || {})[id]
57190
+ splomStash: ((layoutOut._splomAxes || {})[axLetter] || {})[axId]
57150
57191
  };
57151
57192
 
57152
57193
  coerce('uirevision', layoutOut.uirevision);
@@ -57172,12 +57213,63 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57172
57213
  handlePositionDefaults(axLayoutIn, axLayoutOut, coerce, {
57173
57214
  letter: axLetter,
57174
57215
  counterAxes: counterAxes[axLetter],
57175
- overlayableAxes: overlayableAxes,
57216
+ overlayableAxes: getOverlayableAxes(axLetter, axName),
57176
57217
  grid: layoutOut.grid
57177
57218
  });
57178
57219
 
57179
57220
  coerce('title.standoff');
57180
57221
 
57222
+ addMissingMatchedAxis();
57223
+
57224
+ axLayoutOut._input = axLayoutIn;
57225
+ }
57226
+
57227
+ // coerce the 'missing' axes
57228
+ i = 0;
57229
+ while(i < missingMatchedAxisIds.length) {
57230
+ axId = missingMatchedAxisIds[i++];
57231
+ axName = id2name(axId);
57232
+ axLetter = axName.charAt(0);
57233
+
57234
+ if(!Lib.isPlainObject(layoutIn[axName])) {
57235
+ layoutIn[axName] = {};
57236
+ }
57237
+
57238
+ axLayoutIn = layoutIn[axName];
57239
+ axLayoutOut = Template.newContainer(layoutOut, axName, axLetter + 'axis');
57240
+ newAxLayoutOut();
57241
+
57242
+ var defaultOptions2 = {
57243
+ letter: axLetter,
57244
+ font: layoutOut.font,
57245
+ outerTicks: outerTicks[axName],
57246
+ showGrid: !noGrids[axName],
57247
+ data: [],
57248
+ bgColor: bgColor,
57249
+ calendar: layoutOut.calendar,
57250
+ automargin: true,
57251
+ visibleDflt: false,
57252
+ reverseDflt: false,
57253
+ splomStash: ((layoutOut._splomAxes || {})[axLetter] || {})[axId]
57254
+ };
57255
+
57256
+ coerce('uirevision', layoutOut.uirevision);
57257
+
57258
+ axLayoutOut.type = missingMatchedAxisIdsLookup[axId] || 'linear';
57259
+
57260
+ handleAxisDefaults(axLayoutIn, axLayoutOut, coerce, defaultOptions2, layoutOut);
57261
+
57262
+ handlePositionDefaults(axLayoutIn, axLayoutOut, coerce, {
57263
+ letter: axLetter,
57264
+ counterAxes: counterAxes[axLetter],
57265
+ overlayableAxes: getOverlayableAxes(axLetter, axName),
57266
+ grid: layoutOut.grid
57267
+ });
57268
+
57269
+ coerce('fixedrange');
57270
+
57271
+ addMissingMatchedAxis();
57272
+
57181
57273
  axLayoutOut._input = axLayoutIn;
57182
57274
  }
57183
57275
 
@@ -57228,9 +57320,12 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57228
57320
  var constraintGroups = layoutOut._axisConstraintGroups = [];
57229
57321
  // similar to _axisConstraintGroups, but for matching axes
57230
57322
  var matchGroups = layoutOut._axisMatchGroups = [];
57323
+ // make sure to include 'missing' axes here
57324
+ var allAxisIdsIncludingMissing = allAxisIds.concat(missingMatchedAxisIds);
57325
+ var axNamesIncludingMissing = axNames.concat(Lib.simpleMap(missingMatchedAxisIds, id2name));
57231
57326
 
57232
- for(i = 0; i < axNames.length; i++) {
57233
- axName = axNames[i];
57327
+ for(i = 0; i < axNamesIncludingMissing.length; i++) {
57328
+ axName = axNamesIncludingMissing[i];
57234
57329
  axLetter = axName.charAt(0);
57235
57330
  axLayoutIn = layoutIn[axName];
57236
57331
  axLayoutOut = layoutOut[axName];
@@ -57238,15 +57333,19 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57238
57333
  var scaleanchorDflt;
57239
57334
  if(axLetter === 'y' && !axLayoutIn.hasOwnProperty('scaleanchor') && axHasImage[axName]) {
57240
57335
  scaleanchorDflt = axLayoutOut.anchor;
57241
- } else {scaleanchorDflt = undefined;}
57336
+ } else {
57337
+ scaleanchorDflt = undefined;
57338
+ }
57242
57339
 
57243
57340
  var constrainDflt;
57244
57341
  if(!axLayoutIn.hasOwnProperty('constrain') && axHasImage[axName]) {
57245
57342
  constrainDflt = 'domain';
57246
- } else {constrainDflt = undefined;}
57343
+ } else {
57344
+ constrainDflt = undefined;
57345
+ }
57247
57346
 
57248
57347
  handleConstraintDefaults(axLayoutIn, axLayoutOut, coerce, {
57249
- allAxisIds: allAxisIds,
57348
+ allAxisIds: allAxisIdsIncludingMissing,
57250
57349
  layoutOut: layoutOut,
57251
57350
  scaleanchorDflt: scaleanchorDflt,
57252
57351
  constrainDflt: constrainDflt
@@ -57257,7 +57356,6 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57257
57356
  var group = matchGroups[i];
57258
57357
  var rng = null;
57259
57358
  var autorange = null;
57260
- var axId;
57261
57359
 
57262
57360
  // find 'matching' range attrs
57263
57361
  for(axId in group) {
@@ -57310,7 +57408,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57310
57408
  }
57311
57409
  };
57312
57410
 
57313
- },{"../../components/color":42,"../../lib":159,"../../plot_api/plot_template":193,"../../registry":243,"../layout_attributes":233,"./axis_defaults":205,"./axis_ids":206,"./constraints":210,"./layout_attributes":215,"./position_defaults":218,"./type_defaults":226}],217:[function(_dereq_,module,exports){
57411
+ },{"../../components/color":42,"../../lib":159,"../../plot_api/plot_template":193,"../../registry":243,"../layout_attributes":233,"./axis_defaults":205,"./axis_ids":206,"./constants":209,"./constraints":210,"./layout_attributes":215,"./position_defaults":218,"./type_defaults":226}],217:[function(_dereq_,module,exports){
57314
57412
  /**
57315
57413
  * Copyright 2012-2020, Plotly, Inc.
57316
57414
  * All rights reserved.
@@ -61976,10 +62074,13 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac
61976
62074
  var subplots = layout._subplots;
61977
62075
  var subplotId = '';
61978
62076
 
61979
- // TODO - currently if we draw an empty gl2d subplot, it draws
61980
- // nothing then gets stuck and you can't get it back without newPlot
61981
- // sort this out in the regl refactor? but for now just drop empty gl2d subplots
61982
- if(basePlotModule.name !== 'gl2d' || visible) {
62077
+ if(
62078
+ visible ||
62079
+ basePlotModule.name !== 'gl2d' // for now just drop empty gl2d subplots
62080
+ // TODO - currently if we draw an empty gl2d subplot, it draws
62081
+ // nothing then gets stuck and you can't get it back without newPlot
62082
+ // sort this out in the regl refactor?
62083
+ ) {
61983
62084
  if(Array.isArray(subplotAttr)) {
61984
62085
  for(i = 0; i < subplotAttr.length; i++) {
61985
62086
  var attri = subplotAttr[i];
@@ -63638,7 +63739,7 @@ plots.doCalcdata = function(gd, traces) {
63638
63739
  calcdata[i] = cd;
63639
63740
  }
63640
63741
 
63641
- setupAxisCategories(axList, fullData);
63742
+ setupAxisCategories(axList, fullData, fullLayout);
63642
63743
 
63643
63744
  // 'transform' loop - must calc container traces first
63644
63745
  // so that if their dependent traces can get transform properly
@@ -63646,7 +63747,7 @@ plots.doCalcdata = function(gd, traces) {
63646
63747
  for(i = 0; i < fullData.length; i++) transformCalci(i);
63647
63748
 
63648
63749
  // clear stuff that should recomputed in 'regular' loop
63649
- if(hasCalcTransform) setupAxisCategories(axList, fullData);
63750
+ if(hasCalcTransform) setupAxisCategories(axList, fullData, fullLayout);
63650
63751
 
63651
63752
  // 'regular' loop - make sure container traces (eg carpet) calc before
63652
63753
  // contained traces (eg contourcarpet)
@@ -63851,13 +63952,31 @@ function sortAxisCategoriesByValue(axList, gd) {
63851
63952
  return affectedTraces;
63852
63953
  }
63853
63954
 
63854
- function setupAxisCategories(axList, fullData) {
63855
- for(var i = 0; i < axList.length; i++) {
63856
- var ax = axList[i];
63955
+ function setupAxisCategories(axList, fullData, fullLayout) {
63956
+ var axLookup = {};
63957
+ var i, ax, axId;
63958
+
63959
+ for(i = 0; i < axList.length; i++) {
63960
+ ax = axList[i];
63961
+ axId = ax._id;
63962
+
63857
63963
  ax.clearCalc();
63858
63964
  if(ax.type === 'multicategory') {
63859
63965
  ax.setupMultiCategory(fullData);
63860
63966
  }
63967
+
63968
+ axLookup[ax._id] = 1;
63969
+ }
63970
+
63971
+ // look into match groups for 'missing' axes
63972
+ var matchGroups = fullLayout._axisMatchGroups || [];
63973
+ for(i = 0; i < matchGroups.length; i++) {
63974
+ for(axId in matchGroups[i]) {
63975
+ if(!axLookup[axId]) {
63976
+ ax = fullLayout[axisIDs.id2name(axId)];
63977
+ ax.clearCalc();
63978
+ }
63979
+ }
63861
63980
  }
63862
63981
  }
63863
63982
 
@@ -68578,7 +68697,12 @@ function hoverOnBars(pointData, xval, yval, hovermode) {
68578
68697
  var s = di[sizeLetter];
68579
68698
 
68580
68699
  if(isWaterfall) {
68581
- s += Math.abs(di.rawS || 0);
68700
+ var rawS = Math.abs(di.rawS) || 0;
68701
+ if(v > 0) {
68702
+ s += rawS;
68703
+ } else if(v < 0) {
68704
+ s -= rawS;
68705
+ }
68582
68706
  }
68583
68707
 
68584
68708
  // add a gradient so hovering near the end of a
@@ -68965,6 +69089,7 @@ function plot(gd, plotinfo, cdModule, traceLayer, opts, makeOnCompleteCallback)
68965
69089
  !isNumeric(y0) ||
68966
69090
  !isNumeric(y1)
68967
69091
  );
69092
+
68968
69093
  // display zeros if line.width > 0
68969
69094
  if(isBlank && shouldDisplayZeros && helpers.getLineWidth(trace, di) && (isHorizontal ? x1 - x0 === 0 : y1 - y0 === 0)) {
68970
69095
  isBlank = false;
@@ -68974,6 +69099,9 @@ function plot(gd, plotinfo, cdModule, traceLayer, opts, makeOnCompleteCallback)
68974
69099
  if(isBlank && isHorizontal) x1 = x0;
68975
69100
  if(isBlank && !isHorizontal) y1 = y0;
68976
69101
 
69102
+ var spansHorizontal = isHorizontal && (x0 !== x1);
69103
+ var spansVertical = !isHorizontal && (y0 !== y1);
69104
+
68977
69105
  // in waterfall mode `between` we need to adjust bar end points to match the connector width
68978
69106
  if(adjustPixel && !isBlank) {
68979
69107
  if(isHorizontal) {
@@ -69028,10 +69156,15 @@ function plot(gd, plotinfo, cdModule, traceLayer, opts, makeOnCompleteCallback)
69028
69156
 
69029
69157
  var op = Color.opacity(mc);
69030
69158
  var fixpx = (op < 1 || lw > 0.01) ? roundWithLine : expandToVisible;
69031
- x0 = fixpx(x0, x1);
69032
- x1 = fixpx(x1, x0);
69033
- y0 = fixpx(y0, y1);
69034
- y1 = fixpx(y1, y0);
69159
+
69160
+ if(spansHorizontal) {
69161
+ x0 = fixpx(x0, x1);
69162
+ x1 = fixpx(x1, x0);
69163
+ }
69164
+ if(spansVertical) {
69165
+ y0 = fixpx(y0, y1);
69166
+ y1 = fixpx(y1, y0);
69167
+ }
69035
69168
  }
69036
69169
 
69037
69170
  var sel = transition(Lib.ensureSingle(bar, 'path'), fullLayout, opts, makeOnCompleteCallback);