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 (cartesian) v1.52.1
2
+ * plotly.js (cartesian) v1.52.2
3
3
  * Copyright 2012-2020, Plotly, Inc.
4
4
  * All rights reserved.
5
5
  * Licensed under the MIT license
@@ -34481,7 +34481,7 @@ exports.svgAttrs = {
34481
34481
  'use strict';
34482
34482
 
34483
34483
  // package version injected by `npm run preprocess`
34484
- exports.version = '1.52.1';
34484
+ exports.version = '1.52.2';
34485
34485
 
34486
34486
  // inject promise polyfill
34487
34487
  _dereq_('es6-promise').polyfill();
@@ -38068,11 +38068,14 @@ lib.templateString = function(string, obj) {
38068
38068
  var getterCache = {};
38069
38069
 
38070
38070
  return string.replace(lib.TEMPLATE_STRING_REGEX, function(dummy, key) {
38071
+ var v;
38071
38072
  if(SIMPLE_PROPERTY_REGEX.test(key)) {
38072
- return obj[key] || '';
38073
+ v = obj[key];
38074
+ } else {
38075
+ getterCache[key] = getterCache[key] || lib.nestedProperty(obj, key).get;
38076
+ v = getterCache[key]();
38073
38077
  }
38074
- getterCache[key] = getterCache[key] || lib.nestedProperty(obj, key).get;
38075
- return getterCache[key]() || '';
38078
+ return lib.isValidTextValue(v) ? v : '';
38076
38079
  });
38077
38080
  };
38078
38081
 
@@ -48258,6 +48261,7 @@ exports.doAutoRangeAndConstraints = function(gd) {
48258
48261
  var fullLayout = gd._fullLayout;
48259
48262
  var axList = Axes.list(gd, '', true);
48260
48263
  var matchGroups = fullLayout._axisMatchGroups || [];
48264
+ var axLookup = {};
48261
48265
  var ax;
48262
48266
  var axRng;
48263
48267
 
@@ -48265,6 +48269,7 @@ exports.doAutoRangeAndConstraints = function(gd) {
48265
48269
  ax = axList[i];
48266
48270
  cleanAxisConstraints(gd, ax);
48267
48271
  doAutoRange(gd, ax);
48272
+ axLookup[ax._id] = 1;
48268
48273
  }
48269
48274
 
48270
48275
  enforceAxisConstraints(gd);
@@ -48277,6 +48282,10 @@ exports.doAutoRangeAndConstraints = function(gd) {
48277
48282
 
48278
48283
  for(id in group) {
48279
48284
  ax = Axes.getFromId(gd, id);
48285
+
48286
+ // skip over 'missing' axes which do not pass through doAutoRange
48287
+ if(!axLookup[ax._id]) continue;
48288
+ // if one axis has autorange false, we're done
48280
48289
  if(ax.autorange === false) continue groupLoop;
48281
48290
 
48282
48291
  axRng = Lib.simpleMap(ax.range, ax.r2l);
@@ -49154,13 +49163,14 @@ function crawl(objIn, objOut, schema, list, base, path) {
49154
49163
  var valOut = objOut[k];
49155
49164
 
49156
49165
  var nestedSchema = getNestedSchema(schema, k);
49157
- var isInfoArray = (nestedSchema || {}).valType === 'info_array';
49158
- var isColorscale = (nestedSchema || {}).valType === 'colorscale';
49166
+ var nestedValType = (nestedSchema || {}).valType;
49167
+ var isInfoArray = nestedValType === 'info_array';
49168
+ var isColorscale = nestedValType === 'colorscale';
49159
49169
  var items = (nestedSchema || {}).items;
49160
49170
 
49161
49171
  if(!isInSchema(schema, k)) {
49162
49172
  list.push(format('schema', base, p));
49163
- } else if(isPlainObject(valIn) && isPlainObject(valOut)) {
49173
+ } else if(isPlainObject(valIn) && isPlainObject(valOut) && nestedValType !== 'any') {
49164
49174
  crawl(valIn, valOut, nestedSchema, list, base, p);
49165
49175
  } else if(isInfoArray && isArray(valIn)) {
49166
49176
  if(valIn.length > valOut.length) {
@@ -51965,10 +51975,14 @@ axes.drawOne = function(gd, ax, opts) {
51965
51975
  var axId = ax._id;
51966
51976
  var axLetter = axId.charAt(0);
51967
51977
  var counterLetter = axes.counterLetter(axId);
51968
- var mainLinePosition = ax._mainLinePosition;
51969
- var mainMirrorPosition = ax._mainMirrorPosition;
51970
51978
  var mainPlotinfo = fullLayout._plots[ax._mainSubplot];
51979
+
51980
+ // this happens when updating matched group with 'missing' axes
51981
+ if(!mainPlotinfo) return;
51982
+
51971
51983
  var mainAxLayer = mainPlotinfo[axLetter + 'axislayer'];
51984
+ var mainLinePosition = ax._mainLinePosition;
51985
+ var mainMirrorPosition = ax._mainMirrorPosition;
51972
51986
 
51973
51987
  var vals = ax._vals = axes.calcTicks(ax);
51974
51988
 
@@ -53927,11 +53941,10 @@ exports.tick0 = function(tick0, axType, calendar, dtick) {
53927
53941
  */
53928
53942
 
53929
53943
  'use strict';
53930
- var counterRegex = _dereq_('../../lib/regex').counter;
53931
53944
 
53945
+ var counterRegex = _dereq_('../../lib/regex').counter;
53932
53946
 
53933
53947
  module.exports = {
53934
-
53935
53948
  idRegex: {
53936
53949
  x: counterRegex('x'),
53937
53950
  y: counterRegex('y')
@@ -57121,6 +57134,8 @@ var axisIds = _dereq_('./axis_ids');
57121
57134
  var id2name = axisIds.id2name;
57122
57135
  var name2id = axisIds.name2id;
57123
57136
 
57137
+ var AX_ID_PATTERN = _dereq_('./constants').AX_ID_PATTERN;
57138
+
57124
57139
  var Registry = _dereq_('../../registry');
57125
57140
  var traceIs = Registry.traceIs;
57126
57141
  var getComponentMethod = Registry.getComponentMethod;
@@ -57230,7 +57245,28 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57230
57245
 
57231
57246
  var bgColor = Color.combine(plotBgColor, layoutOut.paper_bgcolor);
57232
57247
 
57233
- var axName, axLetter, axLayoutIn, axLayoutOut;
57248
+ // name of single axis (e.g. 'xaxis', 'yaxis2')
57249
+ var axName;
57250
+ // id of single axis (e.g. 'y', 'x5')
57251
+ var axId;
57252
+ // 'x' or 'y'
57253
+ var axLetter;
57254
+ // input layout axis container
57255
+ var axLayoutIn;
57256
+ // full layout axis container
57257
+ var axLayoutOut;
57258
+
57259
+ function newAxLayoutOut() {
57260
+ var traces = ax2traces[axName] || [];
57261
+ axLayoutOut._traceIndices = traces.map(function(t) { return t._expandedIndex; });
57262
+ axLayoutOut._annIndices = [];
57263
+ axLayoutOut._shapeIndices = [];
57264
+ axLayoutOut._imgIndices = [];
57265
+ axLayoutOut._subplotsWith = [];
57266
+ axLayoutOut._counterAxes = [];
57267
+ axLayoutOut._name = axLayoutOut._attr = axName;
57268
+ axLayoutOut._id = axId;
57269
+ }
57234
57270
 
57235
57271
  function coerce(attr, dflt) {
57236
57272
  return Lib.coerce(axLayoutIn, axLayoutOut, layoutAttributes, attr, dflt);
@@ -57244,9 +57280,6 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57244
57280
  return (axLetter === 'x') ? yIds : xIds;
57245
57281
  }
57246
57282
 
57247
- var counterAxes = {x: getCounterAxes('x'), y: getCounterAxes('y')};
57248
- var allAxisIds = counterAxes.x.concat(counterAxes.y);
57249
-
57250
57283
  function getOverlayableAxes(axLetter, axName) {
57251
57284
  var list = (axLetter === 'x') ? xNames : yNames;
57252
57285
  var out = [];
@@ -57262,9 +57295,30 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57262
57295
  return out;
57263
57296
  }
57264
57297
 
57298
+ // list of available counter axis names
57299
+ var counterAxes = {x: getCounterAxes('x'), y: getCounterAxes('y')};
57300
+ // list of all x AND y axis ids
57301
+ var allAxisIds = counterAxes.x.concat(counterAxes.y);
57302
+ // lookup and list of axis ids that axes in axNames have a reference to,
57303
+ // even though they are missing from allAxisIds
57304
+ var missingMatchedAxisIdsLookup = {};
57305
+ var missingMatchedAxisIds = [];
57306
+
57307
+ // fill in 'missing' axis lookup when an axis is set to match an axis
57308
+ // not part of the allAxisIds list, save axis type so that we can propagate
57309
+ // it to the missing axes
57310
+ function addMissingMatchedAxis() {
57311
+ var matchesIn = axLayoutIn.matches;
57312
+ if(AX_ID_PATTERN.test(matchesIn) && allAxisIds.indexOf(matchesIn) === -1) {
57313
+ missingMatchedAxisIdsLookup[matchesIn] = axLayoutIn.type;
57314
+ missingMatchedAxisIds = Object.keys(missingMatchedAxisIdsLookup);
57315
+ }
57316
+ }
57317
+
57265
57318
  // first pass creates the containers, determines types, and handles most of the settings
57266
57319
  for(i = 0; i < axNames.length; i++) {
57267
57320
  axName = axNames[i];
57321
+ axId = name2id(axName);
57268
57322
  axLetter = axName.charAt(0);
57269
57323
 
57270
57324
  if(!Lib.isPlainObject(layoutIn[axName])) {
@@ -57273,20 +57327,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57273
57327
 
57274
57328
  axLayoutIn = layoutIn[axName];
57275
57329
  axLayoutOut = Template.newContainer(layoutOut, axName, axLetter + 'axis');
57276
-
57277
- var traces = ax2traces[axName] || [];
57278
- axLayoutOut._traceIndices = traces.map(function(t) { return t._expandedIndex; });
57279
- axLayoutOut._annIndices = [];
57280
- axLayoutOut._shapeIndices = [];
57281
- axLayoutOut._imgIndices = [];
57282
- axLayoutOut._subplotsWith = [];
57283
- axLayoutOut._counterAxes = [];
57284
-
57285
- // set up some private properties
57286
- axLayoutOut._name = axLayoutOut._attr = axName;
57287
- var id = axLayoutOut._id = name2id(axName);
57288
-
57289
- var overlayableAxes = getOverlayableAxes(axLetter, axName);
57330
+ newAxLayoutOut();
57290
57331
 
57291
57332
  var visibleDflt =
57292
57333
  (axLetter === 'x' && !xaMustDisplay[axName] && xaMayHide[axName]) ||
@@ -57304,13 +57345,13 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57304
57345
  font: layoutOut.font,
57305
57346
  outerTicks: outerTicks[axName],
57306
57347
  showGrid: !noGrids[axName],
57307
- data: traces,
57348
+ data: ax2traces[axName] || [],
57308
57349
  bgColor: bgColor,
57309
57350
  calendar: layoutOut.calendar,
57310
57351
  automargin: true,
57311
57352
  visibleDflt: visibleDflt,
57312
57353
  reverseDflt: reverseDflt,
57313
- splomStash: ((layoutOut._splomAxes || {})[axLetter] || {})[id]
57354
+ splomStash: ((layoutOut._splomAxes || {})[axLetter] || {})[axId]
57314
57355
  };
57315
57356
 
57316
57357
  coerce('uirevision', layoutOut.uirevision);
@@ -57336,12 +57377,63 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57336
57377
  handlePositionDefaults(axLayoutIn, axLayoutOut, coerce, {
57337
57378
  letter: axLetter,
57338
57379
  counterAxes: counterAxes[axLetter],
57339
- overlayableAxes: overlayableAxes,
57380
+ overlayableAxes: getOverlayableAxes(axLetter, axName),
57340
57381
  grid: layoutOut.grid
57341
57382
  });
57342
57383
 
57343
57384
  coerce('title.standoff');
57344
57385
 
57386
+ addMissingMatchedAxis();
57387
+
57388
+ axLayoutOut._input = axLayoutIn;
57389
+ }
57390
+
57391
+ // coerce the 'missing' axes
57392
+ i = 0;
57393
+ while(i < missingMatchedAxisIds.length) {
57394
+ axId = missingMatchedAxisIds[i++];
57395
+ axName = id2name(axId);
57396
+ axLetter = axName.charAt(0);
57397
+
57398
+ if(!Lib.isPlainObject(layoutIn[axName])) {
57399
+ layoutIn[axName] = {};
57400
+ }
57401
+
57402
+ axLayoutIn = layoutIn[axName];
57403
+ axLayoutOut = Template.newContainer(layoutOut, axName, axLetter + 'axis');
57404
+ newAxLayoutOut();
57405
+
57406
+ var defaultOptions2 = {
57407
+ letter: axLetter,
57408
+ font: layoutOut.font,
57409
+ outerTicks: outerTicks[axName],
57410
+ showGrid: !noGrids[axName],
57411
+ data: [],
57412
+ bgColor: bgColor,
57413
+ calendar: layoutOut.calendar,
57414
+ automargin: true,
57415
+ visibleDflt: false,
57416
+ reverseDflt: false,
57417
+ splomStash: ((layoutOut._splomAxes || {})[axLetter] || {})[axId]
57418
+ };
57419
+
57420
+ coerce('uirevision', layoutOut.uirevision);
57421
+
57422
+ axLayoutOut.type = missingMatchedAxisIdsLookup[axId] || 'linear';
57423
+
57424
+ handleAxisDefaults(axLayoutIn, axLayoutOut, coerce, defaultOptions2, layoutOut);
57425
+
57426
+ handlePositionDefaults(axLayoutIn, axLayoutOut, coerce, {
57427
+ letter: axLetter,
57428
+ counterAxes: counterAxes[axLetter],
57429
+ overlayableAxes: getOverlayableAxes(axLetter, axName),
57430
+ grid: layoutOut.grid
57431
+ });
57432
+
57433
+ coerce('fixedrange');
57434
+
57435
+ addMissingMatchedAxis();
57436
+
57345
57437
  axLayoutOut._input = axLayoutIn;
57346
57438
  }
57347
57439
 
@@ -57392,9 +57484,12 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57392
57484
  var constraintGroups = layoutOut._axisConstraintGroups = [];
57393
57485
  // similar to _axisConstraintGroups, but for matching axes
57394
57486
  var matchGroups = layoutOut._axisMatchGroups = [];
57487
+ // make sure to include 'missing' axes here
57488
+ var allAxisIdsIncludingMissing = allAxisIds.concat(missingMatchedAxisIds);
57489
+ var axNamesIncludingMissing = axNames.concat(Lib.simpleMap(missingMatchedAxisIds, id2name));
57395
57490
 
57396
- for(i = 0; i < axNames.length; i++) {
57397
- axName = axNames[i];
57491
+ for(i = 0; i < axNamesIncludingMissing.length; i++) {
57492
+ axName = axNamesIncludingMissing[i];
57398
57493
  axLetter = axName.charAt(0);
57399
57494
  axLayoutIn = layoutIn[axName];
57400
57495
  axLayoutOut = layoutOut[axName];
@@ -57402,15 +57497,19 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57402
57497
  var scaleanchorDflt;
57403
57498
  if(axLetter === 'y' && !axLayoutIn.hasOwnProperty('scaleanchor') && axHasImage[axName]) {
57404
57499
  scaleanchorDflt = axLayoutOut.anchor;
57405
- } else {scaleanchorDflt = undefined;}
57500
+ } else {
57501
+ scaleanchorDflt = undefined;
57502
+ }
57406
57503
 
57407
57504
  var constrainDflt;
57408
57505
  if(!axLayoutIn.hasOwnProperty('constrain') && axHasImage[axName]) {
57409
57506
  constrainDflt = 'domain';
57410
- } else {constrainDflt = undefined;}
57507
+ } else {
57508
+ constrainDflt = undefined;
57509
+ }
57411
57510
 
57412
57511
  handleConstraintDefaults(axLayoutIn, axLayoutOut, coerce, {
57413
- allAxisIds: allAxisIds,
57512
+ allAxisIds: allAxisIdsIncludingMissing,
57414
57513
  layoutOut: layoutOut,
57415
57514
  scaleanchorDflt: scaleanchorDflt,
57416
57515
  constrainDflt: constrainDflt
@@ -57421,7 +57520,6 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57421
57520
  var group = matchGroups[i];
57422
57521
  var rng = null;
57423
57522
  var autorange = null;
57424
- var axId;
57425
57523
 
57426
57524
  // find 'matching' range attrs
57427
57525
  for(axId in group) {
@@ -57474,7 +57572,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
57474
57572
  }
57475
57573
  };
57476
57574
 
57477
- },{"../../components/color":51,"../../lib":169,"../../plot_api/plot_template":203,"../../registry":258,"../layout_attributes":243,"./axis_defaults":215,"./axis_ids":216,"./constraints":220,"./layout_attributes":225,"./position_defaults":228,"./type_defaults":236}],227:[function(_dereq_,module,exports){
57575
+ },{"../../components/color":51,"../../lib":169,"../../plot_api/plot_template":203,"../../registry":258,"../layout_attributes":243,"./axis_defaults":215,"./axis_ids":216,"./constants":219,"./constraints":220,"./layout_attributes":225,"./position_defaults":228,"./type_defaults":236}],227:[function(_dereq_,module,exports){
57478
57576
  /**
57479
57577
  * Copyright 2012-2020, Plotly, Inc.
57480
57578
  * All rights reserved.
@@ -62140,10 +62238,13 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac
62140
62238
  var subplots = layout._subplots;
62141
62239
  var subplotId = '';
62142
62240
 
62143
- // TODO - currently if we draw an empty gl2d subplot, it draws
62144
- // nothing then gets stuck and you can't get it back without newPlot
62145
- // sort this out in the regl refactor? but for now just drop empty gl2d subplots
62146
- if(basePlotModule.name !== 'gl2d' || visible) {
62241
+ if(
62242
+ visible ||
62243
+ basePlotModule.name !== 'gl2d' // for now just drop empty gl2d subplots
62244
+ // TODO - currently if we draw an empty gl2d subplot, it draws
62245
+ // nothing then gets stuck and you can't get it back without newPlot
62246
+ // sort this out in the regl refactor?
62247
+ ) {
62147
62248
  if(Array.isArray(subplotAttr)) {
62148
62249
  for(i = 0; i < subplotAttr.length; i++) {
62149
62250
  var attri = subplotAttr[i];
@@ -63802,7 +63903,7 @@ plots.doCalcdata = function(gd, traces) {
63802
63903
  calcdata[i] = cd;
63803
63904
  }
63804
63905
 
63805
- setupAxisCategories(axList, fullData);
63906
+ setupAxisCategories(axList, fullData, fullLayout);
63806
63907
 
63807
63908
  // 'transform' loop - must calc container traces first
63808
63909
  // so that if their dependent traces can get transform properly
@@ -63810,7 +63911,7 @@ plots.doCalcdata = function(gd, traces) {
63810
63911
  for(i = 0; i < fullData.length; i++) transformCalci(i);
63811
63912
 
63812
63913
  // clear stuff that should recomputed in 'regular' loop
63813
- if(hasCalcTransform) setupAxisCategories(axList, fullData);
63914
+ if(hasCalcTransform) setupAxisCategories(axList, fullData, fullLayout);
63814
63915
 
63815
63916
  // 'regular' loop - make sure container traces (eg carpet) calc before
63816
63917
  // contained traces (eg contourcarpet)
@@ -64015,13 +64116,31 @@ function sortAxisCategoriesByValue(axList, gd) {
64015
64116
  return affectedTraces;
64016
64117
  }
64017
64118
 
64018
- function setupAxisCategories(axList, fullData) {
64019
- for(var i = 0; i < axList.length; i++) {
64020
- var ax = axList[i];
64119
+ function setupAxisCategories(axList, fullData, fullLayout) {
64120
+ var axLookup = {};
64121
+ var i, ax, axId;
64122
+
64123
+ for(i = 0; i < axList.length; i++) {
64124
+ ax = axList[i];
64125
+ axId = ax._id;
64126
+
64021
64127
  ax.clearCalc();
64022
64128
  if(ax.type === 'multicategory') {
64023
64129
  ax.setupMultiCategory(fullData);
64024
64130
  }
64131
+
64132
+ axLookup[ax._id] = 1;
64133
+ }
64134
+
64135
+ // look into match groups for 'missing' axes
64136
+ var matchGroups = fullLayout._axisMatchGroups || [];
64137
+ for(i = 0; i < matchGroups.length; i++) {
64138
+ for(axId in matchGroups[i]) {
64139
+ if(!axLookup[axId]) {
64140
+ ax = fullLayout[axisIDs.id2name(axId)];
64141
+ ax.clearCalc();
64142
+ }
64143
+ }
64025
64144
  }
64026
64145
  }
64027
64146
 
@@ -69907,7 +70026,12 @@ function hoverOnBars(pointData, xval, yval, hovermode) {
69907
70026
  var s = di[sizeLetter];
69908
70027
 
69909
70028
  if(isWaterfall) {
69910
- s += Math.abs(di.rawS || 0);
70029
+ var rawS = Math.abs(di.rawS) || 0;
70030
+ if(v > 0) {
70031
+ s += rawS;
70032
+ } else if(v < 0) {
70033
+ s -= rawS;
70034
+ }
69911
70035
  }
69912
70036
 
69913
70037
  // add a gradient so hovering near the end of a
@@ -70294,6 +70418,7 @@ function plot(gd, plotinfo, cdModule, traceLayer, opts, makeOnCompleteCallback)
70294
70418
  !isNumeric(y0) ||
70295
70419
  !isNumeric(y1)
70296
70420
  );
70421
+
70297
70422
  // display zeros if line.width > 0
70298
70423
  if(isBlank && shouldDisplayZeros && helpers.getLineWidth(trace, di) && (isHorizontal ? x1 - x0 === 0 : y1 - y0 === 0)) {
70299
70424
  isBlank = false;
@@ -70303,6 +70428,9 @@ function plot(gd, plotinfo, cdModule, traceLayer, opts, makeOnCompleteCallback)
70303
70428
  if(isBlank && isHorizontal) x1 = x0;
70304
70429
  if(isBlank && !isHorizontal) y1 = y0;
70305
70430
 
70431
+ var spansHorizontal = isHorizontal && (x0 !== x1);
70432
+ var spansVertical = !isHorizontal && (y0 !== y1);
70433
+
70306
70434
  // in waterfall mode `between` we need to adjust bar end points to match the connector width
70307
70435
  if(adjustPixel && !isBlank) {
70308
70436
  if(isHorizontal) {
@@ -70357,10 +70485,15 @@ function plot(gd, plotinfo, cdModule, traceLayer, opts, makeOnCompleteCallback)
70357
70485
 
70358
70486
  var op = Color.opacity(mc);
70359
70487
  var fixpx = (op < 1 || lw > 0.01) ? roundWithLine : expandToVisible;
70360
- x0 = fixpx(x0, x1);
70361
- x1 = fixpx(x1, x0);
70362
- y0 = fixpx(y0, y1);
70363
- y1 = fixpx(y1, y0);
70488
+
70489
+ if(spansHorizontal) {
70490
+ x0 = fixpx(x0, x1);
70491
+ x1 = fixpx(x1, x0);
70492
+ }
70493
+ if(spansVertical) {
70494
+ y0 = fixpx(y0, y1);
70495
+ y1 = fixpx(y1, y0);
70496
+ }
70364
70497
  }
70365
70498
 
70366
70499
  var sel = transition(Lib.ensureSingle(bar, 'path'), fullLayout, opts, makeOnCompleteCallback);