11/**
2- * plotly.js (cartesian) v2.26.0
2+ * plotly.js (cartesian) v2.26.1
33* Copyright 2012-2023, Plotly, Inc.
44* All rights reserved.
55* Licensed under the MIT license
@@ -11294,6 +11294,23 @@ module.exports = function draw(gd, opts) {
1129411294 }
1129511295 }
1129611296};
11297+
11298+ // After legend dimensions are calculated the title can be aligned horizontally left, center, right
11299+ function horizontalAlignTitle(titleEl, legendObj, bw) {
11300+ if (legendObj.title.side !== 'top center' && legendObj.title.side !== 'top right') return;
11301+ var font = legendObj.title.font;
11302+ var lineHeight = font.size * LINE_SPACING;
11303+ var titleOffset = 0;
11304+ var textNode = titleEl.node();
11305+ var width = Drawing.bBox(textNode).width; // width of the title text
11306+
11307+ if (legendObj.title.side === 'top center') {
11308+ titleOffset = 0.5 * (legendObj._width - 2 * bw - 2 * constants.titlePad - width);
11309+ } else if (legendObj.title.side === 'top right') {
11310+ titleOffset = legendObj._width - 2 * bw - 2 * constants.titlePad - width;
11311+ }
11312+ svgTextUtils.positionText(titleEl, bw + constants.titlePad + titleOffset, bw + lineHeight);
11313+ }
1129711314function drawOne(gd, opts) {
1129811315 var legendObj = opts || {};
1129911316 var fullLayout = gd._fullLayout;
@@ -11370,8 +11387,9 @@ function drawOne(gd, opts) {
1137011387 var title = legendObj.title;
1137111388 legendObj._titleWidth = 0;
1137211389 legendObj._titleHeight = 0;
11390+ var titleEl;
1137311391 if (title.text) {
11374- var titleEl = Lib.ensureSingle(scrollBox, 'text', legendId + 'titletext');
11392+ titleEl = Lib.ensureSingle(scrollBox, 'text', legendId + 'titletext');
1137511393 titleEl.attr('text-anchor', 'start').call(Drawing.font, title.font).text(title.text);
1137611394 textLayout(titleEl, scrollBox, gd, legendObj, MAIN_TITLE); // handle mathjax or multi-line text and compute title height
1137711395 } else {
@@ -11405,6 +11423,11 @@ function drawOne(gd, opts) {
1140511423 var bw = legendObj.borderwidth;
1140611424 var isPaperX = legendObj.xref === 'paper';
1140711425 var isPaperY = legendObj.yref === 'paper';
11426+
11427+ // re-calculate title position after legend width is derived. To allow for horizontal alignment
11428+ if (title.text) {
11429+ horizontalAlignTitle(titleEl, legendObj, bw);
11430+ }
1140811431 if (!inHover) {
1140911432 var lx, ly;
1141011433 if (isPaperX) {
@@ -11621,8 +11644,8 @@ function clickOrDoubleClick(gd, legend, legendItem, numClicks, evt) {
1162111644 evtData.label = legendItem.datum()[0].label;
1162211645 }
1162311646 var clickVal = Events.triggerHandler(gd, 'plotly_legendclick', evtData);
11624- if (clickVal === false) return;
1162511647 if (numClicks === 1) {
11648+ if (clickVal === false) return;
1162611649 legend._clickTimeout = setTimeout(function () {
1162711650 if (!gd._fullLayout) return;
1162811651 handleClick(legendItem, gd, numClicks);
@@ -11631,7 +11654,8 @@ function clickOrDoubleClick(gd, legend, legendItem, numClicks, evt) {
1163111654 if (legend._clickTimeout) clearTimeout(legend._clickTimeout);
1163211655 gd._legendMouseDownTime = 0;
1163311656 var dblClickVal = Events.triggerHandler(gd, 'plotly_legenddoubleclick', evtData);
11634- if (dblClickVal !== false) handleClick(legendItem, gd, numClicks);
11657+ // Activate default double click behaviour only when both single click and double click values are not false
11658+ if (dblClickVal !== false && clickVal !== false) handleClick(legendItem, gd, numClicks);
1163511659 }
1163611660}
1163711661function drawTexts(g, gd, legendObj) {
@@ -11783,16 +11807,11 @@ function computeTextDimensions(g, gd, legendObj, aTitle) {
1178311807 // approximation to height offset to center the font
1178411808 // to avoid getBoundingClientRect
1178511809 if (aTitle === MAIN_TITLE) {
11786- var titleOffset = 0;
1178711810 if (legendObj.title.side === 'left') {
1178811811 // add extra space between legend title and itmes
1178911812 width += constants.itemGap * 2;
11790- } else if (legendObj.title.side === 'top center') {
11791- if (legendObj._width) titleOffset = 0.5 * (legendObj._width - 2 * bw - 2 * constants.titlePad - width);
11792- } else if (legendObj.title.side === 'top right') {
11793- if (legendObj._width) titleOffset = legendObj._width - 2 * bw - 2 * constants.titlePad - width;
1179411813 }
11795- svgTextUtils.positionText(textEl, bw + constants.titlePad + titleOffset , bw + lineHeight);
11814+ svgTextUtils.positionText(textEl, bw + constants.titlePad, bw + lineHeight);
1179611815 } else {
1179711816 // legend item
1179811817 var x = constants.itemGap * 2 + legendObj.itemwidth;
@@ -62258,7 +62277,8 @@ function calcAllAutoBins(gd, trace, pa, mainData, _overlayEdgeCase) {
6225862277
6225962278 // Edge case: single-valued histogram overlaying others
6226062279 // Use them all together to calculate the bin size for the single-valued one
62261- if (isOverlay && !Registry.traceIs(trace, '2dMap') && newBinSpec._dataSpan === 0 && pa.type !== 'category' && pa.type !== 'multicategory') {
62280+ // Don't re-calculate bin width if user manually specified it (checing in bingroup=='' or xbins is defined)
62281+ if (isOverlay && !Registry.traceIs(trace, '2dMap') && newBinSpec._dataSpan === 0 && pa.type !== 'category' && pa.type !== 'multicategory' && trace.bingroup === '' && typeof trace.xbins === 'undefined') {
6226262282 // Several single-valued histograms! Stop infinite recursion,
6226362283 // just return an extra flag that tells handleSingleValueOverlays
6226462284 // to sort out this trace too
@@ -70977,7 +70997,7 @@ function getSortFunc(opts, d2c) {
7097770997
7097870998
7097970999// package version injected by `npm run preprocess`
70980- exports.version = '2.26.0 ';
71000+ exports.version = '2.26.1 ';
7098171001
7098271002/***/ }),
7098371003
0 commit comments