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 (finance) v1.52.1
2
+ * plotly.js (finance) v1.52.2
3
3
  * Copyright 2012-2020, Plotly, Inc.
4
4
  * All rights reserved.
5
5
  * Licensed under the MIT license
@@ -34437,7 +34437,7 @@ exports.svgAttrs = {
34437
34437
  'use strict';
34438
34438
 
34439
34439
  // package version injected by `npm run preprocess`
34440
- exports.version = '1.52.1';
34440
+ exports.version = '1.52.2';
34441
34441
 
34442
34442
  // inject promise polyfill
34443
34443
  _dereq_('es6-promise').polyfill();
@@ -38024,11 +38024,14 @@ lib.templateString = function(string, obj) {
38024
38024
  var getterCache = {};
38025
38025
 
38026
38026
  return string.replace(lib.TEMPLATE_STRING_REGEX, function(dummy, key) {
38027
+ var v;
38027
38028
  if(SIMPLE_PROPERTY_REGEX.test(key)) {
38028
- return obj[key] || '';
38029
+ v = obj[key];
38030
+ } else {
38031
+ getterCache[key] = getterCache[key] || lib.nestedProperty(obj, key).get;
38032
+ v = getterCache[key]();
38029
38033
  }
38030
- getterCache[key] = getterCache[key] || lib.nestedProperty(obj, key).get;
38031
- return getterCache[key]() || '';
38034
+ return lib.isValidTextValue(v) ? v : '';
38032
38035
  });
38033
38036
  };
38034
38037
 
@@ -48214,6 +48217,7 @@ exports.doAutoRangeAndConstraints = function(gd) {
48214
48217
  var fullLayout = gd._fullLayout;
48215
48218
  var axList = Axes.list(gd, '', true);
48216
48219
  var matchGroups = fullLayout._axisMatchGroups || [];
48220
+ var axLookup = {};
48217
48221
  var ax;
48218
48222
  var axRng;
48219
48223
 
@@ -48221,6 +48225,7 @@ exports.doAutoRangeAndConstraints = function(gd) {
48221
48225
  ax = axList[i];
48222
48226
  cleanAxisConstraints(gd, ax);
48223
48227
  doAutoRange(gd, ax);
48228
+ axLookup[ax._id] = 1;
48224
48229
  }
48225
48230
 
48226
48231
  enforceAxisConstraints(gd);
@@ -48233,6 +48238,10 @@ exports.doAutoRangeAndConstraints = function(gd) {
48233
48238
 
48234
48239
  for(id in group) {
48235
48240
  ax = Axes.getFromId(gd, id);
48241
+
48242
+ // skip over 'missing' axes which do not pass through doAutoRange
48243
+ if(!axLookup[ax._id]) continue;
48244
+ // if one axis has autorange false, we're done
48236
48245
  if(ax.autorange === false) continue groupLoop;
48237
48246
 
48238
48247
  axRng = Lib.simpleMap(ax.range, ax.r2l);
@@ -49110,13 +49119,14 @@ function crawl(objIn, objOut, schema, list, base, path) {
49110
49119
  var valOut = objOut[k];
49111
49120
 
49112
49121
  var nestedSchema = getNestedSchema(schema, k);
49113
- var isInfoArray = (nestedSchema || {}).valType === 'info_array';
49114
- var isColorscale = (nestedSchema || {}).valType === 'colorscale';
49122
+ var nestedValType = (nestedSchema || {}).valType;
49123
+ var isInfoArray = nestedValType === 'info_array';
49124
+ var isColorscale = nestedValType === 'colorscale';
49115
49125
  var items = (nestedSchema || {}).items;
49116
49126
 
49117
49127
  if(!isInSchema(schema, k)) {
49118
49128
  list.push(format('schema', base, p));
49119
- } else if(isPlainObject(valIn) && isPlainObject(valOut)) {
49129
+ } else if(isPlainObject(valIn) && isPlainObject(valOut) && nestedValType !== 'any') {
49120
49130
  crawl(valIn, valOut, nestedSchema, list, base, p);
49121
49131
  } else if(isInfoArray && isArray(valIn)) {
49122
49132
  if(valIn.length > valOut.length) {
@@ -51921,10 +51931,14 @@ axes.drawOne = function(gd, ax, opts) {
51921
51931
  var axId = ax._id;
51922
51932
  var axLetter = axId.charAt(0);
51923
51933
  var counterLetter = axes.counterLetter(axId);
51924
- var mainLinePosition = ax._mainLinePosition;
51925
- var mainMirrorPosition = ax._mainMirrorPosition;
51926
51934
  var mainPlotinfo = fullLayout._plots[ax._mainSubplot];
51935
+
51936
+ // this happens when updating matched group with 'missing' axes
51937
+ if(!mainPlotinfo) return;
51938
+
51927
51939
  var mainAxLayer = mainPlotinfo[axLetter + 'axislayer'];
51940
+ var mainLinePosition = ax._mainLinePosition;
51941
+ var mainMirrorPosition = ax._mainMirrorPosition;
51928
51942
 
51929
51943
  var vals = ax._vals = axes.calcTicks(ax);
51930
51944
 
@@ -53883,11 +53897,10 @@ exports.tick0 = function(tick0, axType, calendar, dtick) {
53883
53897
  */
53884
53898
 
53885
53899
  'use strict';
53886
- var counterRegex = _dereq_('../../lib/regex').counter;
53887
53900
 
53901
+ var counterRegex = _dereq_('../../lib/regex').counter;
53888
53902
 
53889
53903
  module.exports = {
53890
-
53891
53904
  idRegex: {
53892
53905
  x: counterRegex('x'),
53893
53906
  y: counterRegex('y')
@@ -57077,6 +57090,8 @@ var axisIds = _dereq_('./axis_ids');
57077
57090
  var id2name = axisIds.id2name;
57078
57091
  var name2id = axisIds.name2id;
57079
57092
 
57093
+ var AX_ID_PATTERN = _dereq_('./constants').AX_ID_PATTERN;
57094
+
57080
57095
  var Registry = _dereq_('../../registry');
57081
57096
  var traceIs = Registry.traceIs;
57082
57097
  var getComponentMethod = Registry.getComponentMethod;
@@ -57186,7 +57201,28 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57186
57201
 
57187
57202
  var bgColor = Color.combine(plotBgColor, layoutOut.paper_bgcolor);
57188
57203
 
57189
- var axName, axLetter, axLayoutIn, axLayoutOut;
57204
+ // name of single axis (e.g. 'xaxis', 'yaxis2')
57205
+ var axName;
57206
+ // id of single axis (e.g. 'y', 'x5')
57207
+ var axId;
57208
+ // 'x' or 'y'
57209
+ var axLetter;
57210
+ // input layout axis container
57211
+ var axLayoutIn;
57212
+ // full layout axis container
57213
+ var axLayoutOut;
57214
+
57215
+ function newAxLayoutOut() {
57216
+ var traces = ax2traces[axName] || [];
57217
+ axLayoutOut._traceIndices = traces.map(function(t) { return t._expandedIndex; });
57218
+ axLayoutOut._annIndices = [];
57219
+ axLayoutOut._shapeIndices = [];
57220
+ axLayoutOut._imgIndices = [];
57221
+ axLayoutOut._subplotsWith = [];
57222
+ axLayoutOut._counterAxes = [];
57223
+ axLayoutOut._name = axLayoutOut._attr = axName;
57224
+ axLayoutOut._id = axId;
57225
+ }
57190
57226
 
57191
57227
  function coerce(attr, dflt) {
57192
57228
  return Lib.coerce(axLayoutIn, axLayoutOut, layoutAttributes, attr, dflt);
@@ -57200,9 +57236,6 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57200
57236
  return (axLetter === 'x') ? yIds : xIds;
57201
57237
  }
57202
57238
 
57203
- var counterAxes = {x: getCounterAxes('x'), y: getCounterAxes('y')};
57204
- var allAxisIds = counterAxes.x.concat(counterAxes.y);
57205
-
57206
57239
  function getOverlayableAxes(axLetter, axName) {
57207
57240
  var list = (axLetter === 'x') ? xNames : yNames;
57208
57241
  var out = [];
@@ -57218,9 +57251,30 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57218
57251
  return out;
57219
57252
  }
57220
57253
 
57254
+ // list of available counter axis names
57255
+ var counterAxes = {x: getCounterAxes('x'), y: getCounterAxes('y')};
57256
+ // list of all x AND y axis ids
57257
+ var allAxisIds = counterAxes.x.concat(counterAxes.y);
57258
+ // lookup and list of axis ids that axes in axNames have a reference to,
57259
+ // even though they are missing from allAxisIds
57260
+ var missingMatchedAxisIdsLookup = {};
57261
+ var missingMatchedAxisIds = [];
57262
+
57263
+ // fill in 'missing' axis lookup when an axis is set to match an axis
57264
+ // not part of the allAxisIds list, save axis type so that we can propagate
57265
+ // it to the missing axes
57266
+ function addMissingMatchedAxis() {
57267
+ var matchesIn = axLayoutIn.matches;
57268
+ if(AX_ID_PATTERN.test(matchesIn) && allAxisIds.indexOf(matchesIn) === -1) {
57269
+ missingMatchedAxisIdsLookup[matchesIn] = axLayoutIn.type;
57270
+ missingMatchedAxisIds = Object.keys(missingMatchedAxisIdsLookup);
57271
+ }
57272
+ }
57273
+
57221
57274
  // first pass creates the containers, determines types, and handles most of the settings
57222
57275
  for(i = 0; i < axNames.length; i++) {
57223
57276
  axName = axNames[i];
57277
+ axId = name2id(axName);
57224
57278
  axLetter = axName.charAt(0);
57225
57279
 
57226
57280
  if(!Lib.isPlainObject(layoutIn[axName])) {
@@ -57229,20 +57283,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57229
57283
 
57230
57284
  axLayoutIn = layoutIn[axName];
57231
57285
  axLayoutOut = Template.newContainer(layoutOut, axName, axLetter + 'axis');
57232
-
57233
- var traces = ax2traces[axName] || [];
57234
- axLayoutOut._traceIndices = traces.map(function(t) { return t._expandedIndex; });
57235
- axLayoutOut._annIndices = [];
57236
- axLayoutOut._shapeIndices = [];
57237
- axLayoutOut._imgIndices = [];
57238
- axLayoutOut._subplotsWith = [];
57239
- axLayoutOut._counterAxes = [];
57240
-
57241
- // set up some private properties
57242
- axLayoutOut._name = axLayoutOut._attr = axName;
57243
- var id = axLayoutOut._id = name2id(axName);
57244
-
57245
- var overlayableAxes = getOverlayableAxes(axLetter, axName);
57286
+ newAxLayoutOut();
57246
57287
 
57247
57288
  var visibleDflt =
57248
57289
  (axLetter === 'x' && !xaMustDisplay[axName] && xaMayHide[axName]) ||
@@ -57260,13 +57301,13 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57260
57301
  font: layoutOut.font,
57261
57302
  outerTicks: outerTicks[axName],
57262
57303
  showGrid: !noGrids[axName],
57263
- data: traces,
57304
+ data: ax2traces[axName] || [],
57264
57305
  bgColor: bgColor,
57265
57306
  calendar: layoutOut.calendar,
57266
57307
  automargin: true,
57267
57308
  visibleDflt: visibleDflt,
57268
57309
  reverseDflt: reverseDflt,
57269
- splomStash: ((layoutOut._splomAxes || {})[axLetter] || {})[id]
57310
+ splomStash: ((layoutOut._splomAxes || {})[axLetter] || {})[axId]
57270
57311
  };
57271
57312
 
57272
57313
  coerce('uirevision', layoutOut.uirevision);
@@ -57292,12 +57333,63 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57292
57333
  handlePositionDefaults(axLayoutIn, axLayoutOut, coerce, {
57293
57334
  letter: axLetter,
57294
57335
  counterAxes: counterAxes[axLetter],
57295
- overlayableAxes: overlayableAxes,
57336
+ overlayableAxes: getOverlayableAxes(axLetter, axName),
57296
57337
  grid: layoutOut.grid
57297
57338
  });
57298
57339
 
57299
57340
  coerce('title.standoff');
57300
57341
 
57342
+ addMissingMatchedAxis();
57343
+
57344
+ axLayoutOut._input = axLayoutIn;
57345
+ }
57346
+
57347
+ // coerce the 'missing' axes
57348
+ i = 0;
57349
+ while(i < missingMatchedAxisIds.length) {
57350
+ axId = missingMatchedAxisIds[i++];
57351
+ axName = id2name(axId);
57352
+ axLetter = axName.charAt(0);
57353
+
57354
+ if(!Lib.isPlainObject(layoutIn[axName])) {
57355
+ layoutIn[axName] = {};
57356
+ }
57357
+
57358
+ axLayoutIn = layoutIn[axName];
57359
+ axLayoutOut = Template.newContainer(layoutOut, axName, axLetter + 'axis');
57360
+ newAxLayoutOut();
57361
+
57362
+ var defaultOptions2 = {
57363
+ letter: axLetter,
57364
+ font: layoutOut.font,
57365
+ outerTicks: outerTicks[axName],
57366
+ showGrid: !noGrids[axName],
57367
+ data: [],
57368
+ bgColor: bgColor,
57369
+ calendar: layoutOut.calendar,
57370
+ automargin: true,
57371
+ visibleDflt: false,
57372
+ reverseDflt: false,
57373
+ splomStash: ((layoutOut._splomAxes || {})[axLetter] || {})[axId]
57374
+ };
57375
+
57376
+ coerce('uirevision', layoutOut.uirevision);
57377
+
57378
+ axLayoutOut.type = missingMatchedAxisIdsLookup[axId] || 'linear';
57379
+
57380
+ handleAxisDefaults(axLayoutIn, axLayoutOut, coerce, defaultOptions2, layoutOut);
57381
+
57382
+ handlePositionDefaults(axLayoutIn, axLayoutOut, coerce, {
57383
+ letter: axLetter,
57384
+ counterAxes: counterAxes[axLetter],
57385
+ overlayableAxes: getOverlayableAxes(axLetter, axName),
57386
+ grid: layoutOut.grid
57387
+ });
57388
+
57389
+ coerce('fixedrange');
57390
+
57391
+ addMissingMatchedAxis();
57392
+
57301
57393
  axLayoutOut._input = axLayoutIn;
57302
57394
  }
57303
57395
 
@@ -57348,9 +57440,12 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57348
57440
  var constraintGroups = layoutOut._axisConstraintGroups = [];
57349
57441
  // similar to _axisConstraintGroups, but for matching axes
57350
57442
  var matchGroups = layoutOut._axisMatchGroups = [];
57443
+ // make sure to include 'missing' axes here
57444
+ var allAxisIdsIncludingMissing = allAxisIds.concat(missingMatchedAxisIds);
57445
+ var axNamesIncludingMissing = axNames.concat(Lib.simpleMap(missingMatchedAxisIds, id2name));
57351
57446
 
57352
- for(i = 0; i < axNames.length; i++) {
57353
- axName = axNames[i];
57447
+ for(i = 0; i < axNamesIncludingMissing.length; i++) {
57448
+ axName = axNamesIncludingMissing[i];
57354
57449
  axLetter = axName.charAt(0);
57355
57450
  axLayoutIn = layoutIn[axName];
57356
57451
  axLayoutOut = layoutOut[axName];
@@ -57358,15 +57453,19 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57358
57453
  var scaleanchorDflt;
57359
57454
  if(axLetter === 'y' && !axLayoutIn.hasOwnProperty('scaleanchor') && axHasImage[axName]) {
57360
57455
  scaleanchorDflt = axLayoutOut.anchor;
57361
- } else {scaleanchorDflt = undefined;}
57456
+ } else {
57457
+ scaleanchorDflt = undefined;
57458
+ }
57362
57459
 
57363
57460
  var constrainDflt;
57364
57461
  if(!axLayoutIn.hasOwnProperty('constrain') && axHasImage[axName]) {
57365
57462
  constrainDflt = 'domain';
57366
- } else {constrainDflt = undefined;}
57463
+ } else {
57464
+ constrainDflt = undefined;
57465
+ }
57367
57466
 
57368
57467
  handleConstraintDefaults(axLayoutIn, axLayoutOut, coerce, {
57369
- allAxisIds: allAxisIds,
57468
+ allAxisIds: allAxisIdsIncludingMissing,
57370
57469
  layoutOut: layoutOut,
57371
57470
  scaleanchorDflt: scaleanchorDflt,
57372
57471
  constrainDflt: constrainDflt
@@ -57377,7 +57476,6 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57377
57476
  var group = matchGroups[i];
57378
57477
  var rng = null;
57379
57478
  var autorange = null;
57380
- var axId;
57381
57479
 
57382
57480
  // find 'matching' range attrs
57383
57481
  for(axId in group) {
@@ -57430,7 +57528,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57430
57528
  }
57431
57529
  };
57432
57530
 
57433
- },{"../../components/color":49,"../../lib":167,"../../plot_api/plot_template":201,"../../registry":251,"../layout_attributes":241,"./axis_defaults":213,"./axis_ids":214,"./constraints":218,"./layout_attributes":223,"./position_defaults":226,"./type_defaults":234}],225:[function(_dereq_,module,exports){
57531
+ },{"../../components/color":49,"../../lib":167,"../../plot_api/plot_template":201,"../../registry":251,"../layout_attributes":241,"./axis_defaults":213,"./axis_ids":214,"./constants":217,"./constraints":218,"./layout_attributes":223,"./position_defaults":226,"./type_defaults":234}],225:[function(_dereq_,module,exports){
57434
57532
  /**
57435
57533
  * Copyright 2012-2020, Plotly, Inc.
57436
57534
  * All rights reserved.
@@ -62096,10 +62194,13 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac
62096
62194
  var subplots = layout._subplots;
62097
62195
  var subplotId = '';
62098
62196
 
62099
- // TODO - currently if we draw an empty gl2d subplot, it draws
62100
- // nothing then gets stuck and you can't get it back without newPlot
62101
- // sort this out in the regl refactor? but for now just drop empty gl2d subplots
62102
- if(basePlotModule.name !== 'gl2d' || visible) {
62197
+ if(
62198
+ visible ||
62199
+ basePlotModule.name !== 'gl2d' // for now just drop empty gl2d subplots
62200
+ // TODO - currently if we draw an empty gl2d subplot, it draws
62201
+ // nothing then gets stuck and you can't get it back without newPlot
62202
+ // sort this out in the regl refactor?
62203
+ ) {
62103
62204
  if(Array.isArray(subplotAttr)) {
62104
62205
  for(i = 0; i < subplotAttr.length; i++) {
62105
62206
  var attri = subplotAttr[i];
@@ -63758,7 +63859,7 @@ plots.doCalcdata = function(gd, traces) {
63758
63859
  calcdata[i] = cd;
63759
63860
  }
63760
63861
 
63761
- setupAxisCategories(axList, fullData);
63862
+ setupAxisCategories(axList, fullData, fullLayout);
63762
63863
 
63763
63864
  // 'transform' loop - must calc container traces first
63764
63865
  // so that if their dependent traces can get transform properly
@@ -63766,7 +63867,7 @@ plots.doCalcdata = function(gd, traces) {
63766
63867
  for(i = 0; i < fullData.length; i++) transformCalci(i);
63767
63868
 
63768
63869
  // clear stuff that should recomputed in 'regular' loop
63769
- if(hasCalcTransform) setupAxisCategories(axList, fullData);
63870
+ if(hasCalcTransform) setupAxisCategories(axList, fullData, fullLayout);
63770
63871
 
63771
63872
  // 'regular' loop - make sure container traces (eg carpet) calc before
63772
63873
  // contained traces (eg contourcarpet)
@@ -63971,13 +64072,31 @@ function sortAxisCategoriesByValue(axList, gd) {
63971
64072
  return affectedTraces;
63972
64073
  }
63973
64074
 
63974
- function setupAxisCategories(axList, fullData) {
63975
- for(var i = 0; i < axList.length; i++) {
63976
- var ax = axList[i];
64075
+ function setupAxisCategories(axList, fullData, fullLayout) {
64076
+ var axLookup = {};
64077
+ var i, ax, axId;
64078
+
64079
+ for(i = 0; i < axList.length; i++) {
64080
+ ax = axList[i];
64081
+ axId = ax._id;
64082
+
63977
64083
  ax.clearCalc();
63978
64084
  if(ax.type === 'multicategory') {
63979
64085
  ax.setupMultiCategory(fullData);
63980
64086
  }
64087
+
64088
+ axLookup[ax._id] = 1;
64089
+ }
64090
+
64091
+ // look into match groups for 'missing' axes
64092
+ var matchGroups = fullLayout._axisMatchGroups || [];
64093
+ for(i = 0; i < matchGroups.length; i++) {
64094
+ for(axId in matchGroups[i]) {
64095
+ if(!axLookup[axId]) {
64096
+ ax = fullLayout[axisIDs.id2name(axId)];
64097
+ ax.clearCalc();
64098
+ }
64099
+ }
63981
64100
  }
63982
64101
  }
63983
64102
 
@@ -68698,7 +68817,12 @@ function hoverOnBars(pointData, xval, yval, hovermode) {
68698
68817
  var s = di[sizeLetter];
68699
68818
 
68700
68819
  if(isWaterfall) {
68701
- s += Math.abs(di.rawS || 0);
68820
+ var rawS = Math.abs(di.rawS) || 0;
68821
+ if(v > 0) {
68822
+ s += rawS;
68823
+ } else if(v < 0) {
68824
+ s -= rawS;
68825
+ }
68702
68826
  }
68703
68827
 
68704
68828
  // add a gradient so hovering near the end of a
@@ -69085,6 +69209,7 @@ function plot(gd, plotinfo, cdModule, traceLayer, opts, makeOnCompleteCallback)
69085
69209
  !isNumeric(y0) ||
69086
69210
  !isNumeric(y1)
69087
69211
  );
69212
+
69088
69213
  // display zeros if line.width > 0
69089
69214
  if(isBlank && shouldDisplayZeros && helpers.getLineWidth(trace, di) && (isHorizontal ? x1 - x0 === 0 : y1 - y0 === 0)) {
69090
69215
  isBlank = false;
@@ -69094,6 +69219,9 @@ function plot(gd, plotinfo, cdModule, traceLayer, opts, makeOnCompleteCallback)
69094
69219
  if(isBlank && isHorizontal) x1 = x0;
69095
69220
  if(isBlank && !isHorizontal) y1 = y0;
69096
69221
 
69222
+ var spansHorizontal = isHorizontal && (x0 !== x1);
69223
+ var spansVertical = !isHorizontal && (y0 !== y1);
69224
+
69097
69225
  // in waterfall mode `between` we need to adjust bar end points to match the connector width
69098
69226
  if(adjustPixel && !isBlank) {
69099
69227
  if(isHorizontal) {
@@ -69148,10 +69276,15 @@ function plot(gd, plotinfo, cdModule, traceLayer, opts, makeOnCompleteCallback)
69148
69276
 
69149
69277
  var op = Color.opacity(mc);
69150
69278
  var fixpx = (op < 1 || lw > 0.01) ? roundWithLine : expandToVisible;
69151
- x0 = fixpx(x0, x1);
69152
- x1 = fixpx(x1, x0);
69153
- y0 = fixpx(y0, y1);
69154
- y1 = fixpx(y1, y0);
69279
+
69280
+ if(spansHorizontal) {
69281
+ x0 = fixpx(x0, x1);
69282
+ x1 = fixpx(x1, x0);
69283
+ }
69284
+ if(spansVertical) {
69285
+ y0 = fixpx(y0, y1);
69286
+ y1 = fixpx(y1, y0);
69287
+ }
69155
69288
  }
69156
69289
 
69157
69290
  var sel = transition(Lib.ensureSingle(bar, 'path'), fullLayout, opts, makeOnCompleteCallback);