From 3f473b11d1d05372c7d3b129f9bf3f090044264d Mon Sep 17 00:00:00 2001 From: nickmelnikov82 Date: Wed, 1 Jun 2022 15:18:43 +0300 Subject: [PATCH 1/6] add legendgroup width option --- src/components/legend/attributes.js | 6 + src/components/legend/defaults.js | 1 + src/components/legend/draw.js | 32 ++- src/plots/attributes.js | 6 + src/plots/plots.js | 1 + test/jasmine/tests/legend_test.js | 92 +++++++++ test/plot-schema.json | 294 ++++++++++++++++++++++++++++ 7 files changed, 427 insertions(+), 5 deletions(-) diff --git a/src/components/legend/attributes.js b/src/components/legend/attributes.js index f294d2471f0..907e7e83059 100644 --- a/src/components/legend/attributes.js +++ b/src/components/legend/attributes.js @@ -74,6 +74,12 @@ module.exports = { 'Sets the amount of vertical space (in px) between legend groups.' ].join(' ') }, + legendtextwidth: { + valType: 'number', + min: 0, + editType: 'legend', + description: 'Sets the width (in px) of the legend.', + }, itemsizing: { valType: 'enumerated', values: ['trace', 'constant'], diff --git a/src/components/legend/defaults.js b/src/components/legend/defaults.js index 70afc29ab33..63713a2f3f0 100644 --- a/src/components/legend/defaults.js +++ b/src/components/legend/defaults.js @@ -122,6 +122,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) { coerce('traceorder', defaultOrder); if(helpers.isGrouped(layoutOut.legend)) coerce('tracegroupgap'); + coerce('legendtextwidth'); coerce('itemsizing'); coerce('itemwidth'); diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index 7d0ff625fb5..ed440c094e8 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -351,6 +351,21 @@ function _draw(gd, legendObj) { }], gd); } +function getTraceWidth(trace, legendObj, textGap, isGrouped) { + var legendItem = trace[0]; + var legendWidth = legendItem.width; + + if(legendItem.trace.legendtextwidth !== undefined) { + legendWidth = legendItem.trace.legendtextwidth; + } else if(isGrouped && legendItem.trace.legendgroup !== '') { + legendWidth = legendItem.width; + } else if(legendObj.legendtextwidth !== undefined) { + legendWidth = legendObj.legendtextwidth; + } + + return legendWidth + textGap; +} + function clickOrDoubleClick(gd, legend, legendItem, numClicks, evt) { var trace = legendItem.data()[0][0].trace; var evtData = { @@ -636,6 +651,7 @@ function computeLegendDimensions(gd, groups, traces, legendObj) { var isAbovePlotArea = legendObj.y > 1 || (legendObj.y === 1 && yanchor === 'bottom'); var traceGroupGap = legendObj.tracegroupgap; + var legendGroupWidths = {}; // - if below/above plot area, give it the maximum potential margin-push value // - otherwise, extend the height of the plot area @@ -688,7 +704,7 @@ function computeLegendDimensions(gd, groups, traces, legendObj) { var maxItemWidth = 0; var combinedItemWidth = 0; traces.each(function(d) { - var w = d[0].width + textGap; + var w = getTraceWidth(d, legendObj, textGap, isGrouped); maxItemWidth = Math.max(maxItemWidth, w); combinedItemWidth += w; }); @@ -704,7 +720,7 @@ function computeLegendDimensions(gd, groups, traces, legendObj) { var maxWidthInGroup = 0; var offsetY = 0; d3.select(this).selectAll('g.traces').each(function(d) { - var w = d[0].width; + var w = getTraceWidth(d, legendObj, textGap, isGrouped); var h = d[0].height; Drawing.setTranslate(this, @@ -712,7 +728,8 @@ function computeLegendDimensions(gd, groups, traces, legendObj) { titleSize[1] + bw + itemGap + h / 2 + offsetY ); offsetY += h; - maxWidthInGroup = Math.max(maxWidthInGroup, textGap + w); + maxWidthInGroup = Math.max(maxWidthInGroup, w); + legendGroupWidths[d[0].trace.legendgroup] = maxWidthInGroup; }); var next = maxWidthInGroup + itemGap; @@ -750,7 +767,7 @@ function computeLegendDimensions(gd, groups, traces, legendObj) { var rowWidth = 0; traces.each(function(d) { var h = d[0].height; - var w = textGap + d[0].width; + var w = getTraceWidth(d, legendObj, textGap, isGrouped); var next = (oneRowLegend ? w : maxItemWidth) + itemGap; if((next + bw + offsetX - itemGap) >= legendObj._maxWidth) { @@ -802,7 +819,12 @@ function computeLegendDimensions(gd, groups, traces, legendObj) { traces.each(function(d) { var traceToggle = d3.select(this).select('.legendtoggle'); var h = d[0].height; - var w = isEditable ? textGap : (toggleRectWidth || (textGap + d[0].width)); + var legendgroup = d[0].trace.legendgroup; + var traceWidth = getTraceWidth(d, legendObj, textGap); + if(isGrouped && legendgroup !== '') { + traceWidth = legendGroupWidths[legendgroup]; + } + var w = isEditable ? textGap : (toggleRectWidth || traceWidth); if(!isVertical) w += itemGap / 2; Drawing.setRect(traceToggle, 0, -h / 2, w, h); }); diff --git a/src/plots/attributes.js b/src/plots/attributes.js index f90582ec200..3653a5c03f7 100644 --- a/src/plots/attributes.js +++ b/src/plots/attributes.js @@ -72,6 +72,12 @@ module.exports = { 'and ranks greater than 1000 to go after all unranked items.' ].join(' ') }, + legendtextwidth: { + valType: 'number', + min: 0, + editType: 'style', + description: 'Sets the width (in px) of the legend for this trace.', + }, opacity: { valType: 'number', min: 0, diff --git a/src/plots/plots.js b/src/plots/plots.js index cda76cf8f37..1b9981904ed 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -1320,6 +1320,7 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac 'showlegend' ); + coerce('legendtextwidth'); coerce('legendgroup'); coerce('legendgrouptitle.text'); coerce('legendrank'); diff --git a/test/jasmine/tests/legend_test.js b/test/jasmine/tests/legend_test.js index f1c71c12bd3..a198c9bbfbb 100644 --- a/test/jasmine/tests/legend_test.js +++ b/test/jasmine/tests/legend_test.js @@ -6,6 +6,7 @@ var DBLCLICKDELAY = require('@src/plot_api/plot_config').dfltConfig.doubleClickD var Legend = require('@src/components/legend'); var getLegendData = require('@src/components/legend/get_legend_data'); var helpers = require('@src/components/legend/helpers'); +var constants = require('@src/components/legend/constants'); var d3Select = require('../../strict-d3').select; var d3SelectAll = require('../../strict-d3').selectAll; @@ -2345,3 +2346,94 @@ describe('legend with custom doubleClickDelay', function() { .then(done, done.fail); }, 3 * jasmine.DEFAULT_TIMEOUT_INTERVAL); }); + +describe('legend with custom legendtextwidth', function() { + var gd; + + var data = [ + {x: [1, 2, 1], y: [1, 2, 1], name: 'legend text 1'}, + {x: [2, 1, 2], y: [2, 1, 2], name: 'legend text 12'}, + {x: [2, 3, 4], y: [2, 3, 4], name: 'legend text 123'} + ]; + + var layout = { + legend: { + orientation: 'h' + } + }; + + beforeEach(function() { + gd = createGraphDiv(); + }); + + afterEach(destroyGraphDiv); + + function assertLegendTextWidth(variants) { + var nodes = d3SelectAll('rect.legendtoggle'); + var index = 0; + nodes.each(function() { + var node = d3Select(this); + var w = +node.attr('width'); + if(variants[index]) expect(w).toEqual(variants[index]); + index += 1; + }); + } + + it('should change width when trace has legendtextwidth', function(done) { + var extendedData = Lib.extendDeep([], data); + extendedData.forEach(function(trace, index) { + trace.legendtextwidth = (index + 1) * 50; + }); + + var textGap = 30 + constants.itemGap * 2 + constants.itemGap / 2; + + Plotly.newPlot(gd, {data: extendedData, layout: layout}).then(function() { + assertLegendTextWidth([50 + textGap, 100 + textGap, 150 + textGap]); + }).then(done); + }); + + it('should change width when legend has legendtextwidth', function(done) { + var extendedLayout = Lib.extendDeep([], layout); + var width = 50; + extendedLayout.legend.legendtextwidth = width; + + var textGap = 30 + constants.itemGap * 2 + constants.itemGap / 2; + + Plotly.newPlot(gd, {data: data, layout: extendedLayout}).then(function() { + assertLegendTextWidth([width + textGap, width + textGap, width + textGap]); + }).then(done); + }); + + it('should change group width when trace has legendtextwidth', function(done) { + var extendedLayout = Lib.extendDeep([], layout); + extendedLayout.legend.traceorder = 'grouped'; + + var extendedData = Lib.extendDeep([], data); + extendedData[0].legendtextwidth = 100; + extendedData[0].legendgroup = 'test'; + extendedData[1].legendgroup = 'test'; + + var textGap = 30 + constants.itemGap * 2 + constants.itemGap / 2; + + Plotly.newPlot(gd, {data: extendedData, layout: extendedLayout}).then(function() { + assertLegendTextWidth([100 + textGap, 100 + textGap, undefined]); + }).then(done); + }); + + it('should prefer group legendtextwidth to the legend legendtextwidth', function(done) { + var extendedLayout = Lib.extendDeep([], layout); + extendedLayout.legend.traceorder = 'grouped'; + extendedLayout.legend.legendtextwidth = 50; + + var extendedData = Lib.extendDeep([], data); + extendedData[0].legendtextwidth = 100; + extendedData[0].legendgroup = 'test'; + extendedData[1].legendgroup = 'test'; + + var textGap = 30 + constants.itemGap * 2 + constants.itemGap / 2; + + Plotly.newPlot(gd, {data: extendedData, layout: extendedLayout}).then(function() { + assertLegendTextWidth([100 + textGap, 100 + textGap, 50 + textGap]); + }).then(done); + }); +}); diff --git a/test/plot-schema.json b/test/plot-schema.json index e293afda4dc..b5759a11de7 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -2823,6 +2823,12 @@ "min": 30, "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend.", + "editType": "legend", + "min": 0, + "valType": "number" + }, "orientation": { "description": "Sets the orientation of the legend.", "dflt": "v", @@ -12437,6 +12443,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "marker": { "autocolorscale": { "description": "Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `marker.colorscale`. Has an effect only if in `marker.color` is set to a numerical array. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed.", @@ -13952,6 +13964,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "marker": { "autocolorscale": { "description": "Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `marker.colorscale`. Has an effect only if in `marker.color` is set to a numerical array. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed.", @@ -15246,6 +15264,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "color": { "description": "Sets the color of line bounding the box(es).", @@ -16565,6 +16589,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "editType": "style", "role": "object", @@ -18061,6 +18091,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "meta": { "arrayOk": true, "description": "Assigns extra meta information associated with this trace that can be used in various text attributes. Attributes such as trace `name`, graph, axis and colorbar `title.text`, annotation `text` `rangeselector`, `updatemenues` and `sliders` `label` text all support `meta`. To access the trace `meta` values in an attribute in the same trace, simply use `%{meta[i]}` where `i` is the index or key of the `meta` item in question. To access trace `meta` in layout attributes, use `%{data[n[.meta[i]}` where `i` is the index or key of the `meta` and `n` is the trace index.", @@ -18909,6 +18945,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "locationmode": { "description": "Determines the set of locations used to match entries in `locations` to regions on the map. Values *ISO-3*, *USA-states*, *country names* correspond to features on the base map and value *geojson-id* corresponds to features from a custom GeoJSON linked to the `geojson` attribute.", "dflt": "ISO-3", @@ -19896,6 +19938,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "locations": { "description": "Sets which features found in *geojson* to plot using their feature `id` field.", "editType": "calc", @@ -20912,6 +20960,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "lighting": { "ambient": { "description": "Ambient light increases overall color visibility but can wash out the image.", @@ -22104,6 +22158,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "color": { "description": "Sets the color of the contour level. Has no effect if `contours.coloring` is set to *lines*.", @@ -23342,6 +23402,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "color": { "description": "Sets the color of the contour level. Has no effect if `contours.coloring` is set to *lines*.", @@ -24291,6 +24357,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "lon": { "description": "Sets the longitude coordinates (in degrees East).", "editType": "calc", @@ -24822,6 +24894,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "marker": { "autocolorscale": { "description": "Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `marker.colorscale`. Has an effect only if in `marker.color` is set to a numerical array. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed.", @@ -26243,6 +26321,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "marker": { "colors": { "description": "Sets the color of each sector. If not specified, the default trace color set is used to pick the sector colors.", @@ -27313,6 +27397,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "meta": { "arrayOk": true, "description": "Assigns extra meta information associated with this trace that can be used in various text attributes. Attributes such as trace `name`, graph, axis and colorbar `title.text`, annotation `text` `rangeselector`, `updatemenues` and `sliders` `label` text all support `meta`. To access the trace `meta` values in an attribute in the same trace, simply use `%{meta[i]}` where `i` is the index or key of the `meta` item in question. To access trace `meta` in layout attributes, use `%{data[n[.meta[i]}` where `i` is the index or key of the `meta` and `n` is the trace index.", @@ -28438,6 +28528,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "meta": { "arrayOk": true, "description": "Assigns extra meta information associated with this trace that can be used in various text attributes. Attributes such as trace `name`, graph, axis and colorbar `title.text`, annotation `text` `rangeselector`, `updatemenues` and `sliders` `label` text all support `meta`. To access the trace `meta` values in an attribute in the same trace, simply use `%{meta[i]}` where `i` is the index or key of the `meta` item in question. To access trace `meta` in layout attributes, use `%{data[n[.meta[i]}` where `i` is the index or key of the `meta` and `n` is the trace index.", @@ -29225,6 +29321,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "marker": { "autocolorscale": { "description": "Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `marker.colorscale`. Has an effect only if in `marker.color` is set to a numerical array. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed.", @@ -31177,6 +31279,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "marker": { "color": { "description": "Sets the aggregation data.", @@ -32437,6 +32545,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "color": { "description": "Sets the color of the contour level. Has no effect if `contours.coloring` is set to *lines*.", @@ -33188,6 +33302,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "level": { "anim": true, "description": "Sets the level from which this trace hierarchy is rendered. Set `level` to `''` to start from the root node in the hierarchy. Must be an \"id\" if `ids` is filled in, otherwise plotly attempts to find a matching item in `labels`.", @@ -34397,6 +34517,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "meta": { "arrayOk": true, "description": "Assigns extra meta information associated with this trace that can be used in various text attributes. Attributes such as trace `name`, graph, axis and colorbar `title.text`, annotation `text` `rangeselector`, `updatemenues` and `sliders` `label` text all support `meta`. To access the trace `meta` values in an attribute in the same trace, simply use `%{meta[i]}` where `i` is the index or key of the `meta` item in question. To access trace `meta` in layout attributes, use `%{data[n[.meta[i]}` where `i` is the index or key of the `meta` and `n` is the trace index.", @@ -35244,6 +35370,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "meta": { "arrayOk": true, "description": "Assigns extra meta information associated with this trace that can be used in various text attributes. Attributes such as trace `name`, graph, axis and colorbar `title.text`, annotation `text` `rangeselector`, `updatemenues` and `sliders` `label` text all support `meta`. To access the trace `meta` values in an attribute in the same trace, simply use `%{meta[i]}` where `i` is the index or key of the `meta` item in question. To access trace `meta` in layout attributes, use `%{data[n[.meta[i]}` where `i` is the index or key of the `meta` and `n` is the trace index.", @@ -36271,6 +36403,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "lighting": { "ambient": { "description": "Ambient light increases overall color visibility but can wash out the image.", @@ -37548,6 +37686,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "lighting": { "ambient": { "description": "Ambient light increases overall color visibility but can wash out the image.", @@ -38170,6 +38314,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "dash": { "description": "Sets the dash style of lines. Set to a dash type string (*solid*, *dot*, *dash*, *longdash*, *dashdot*, or *longdashdot*) or a dash length list in px (eg *5px,10px,2px,2px*). Note that this style setting can also be set per direction via `increasing.line.dash` and `decreasing.line.dash`.", @@ -38663,6 +38813,12 @@ "valType": "string" } }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "autocolorscale": { "description": "Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `line.colorscale`. Has an effect only if in `line.color` is set to a numerical array. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed.", @@ -39620,6 +39776,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "autocolorscale": { "description": "Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `line.colorscale`. Has an effect only if in `line.color` is set to a numerical array. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed.", @@ -40793,6 +40955,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "marker": { "colors": { "description": "Sets the color of each sector. If not specified, the default trace color set is used to pick the sector colors.", @@ -41385,6 +41553,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "marker": { "blend": { "description": "Determines if colors are blended together for a translucency effect in case `opacity` is specified as a value less then `1`. Setting `blend` to `true` reduces zoom/pan speed if used with large numbers of points.", @@ -41843,6 +42017,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "link": { "color": { "arrayOk": true, @@ -43032,6 +43212,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "color": { "anim": true, @@ -45289,6 +45475,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "autocolorscale": { "description": "Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `line.colorscale`. Has an effect only if in `line.color` is set to a numerical array. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed.", @@ -47272,6 +47464,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "color": { "description": "Sets the line color.", @@ -49093,6 +49291,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "color": { "description": "Sets the line color.", @@ -51093,6 +51297,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "color": { "description": "Sets the line color.", @@ -52992,6 +53202,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "color": { "description": "Sets the line color.", @@ -54157,6 +54373,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "color": { "description": "Sets the line color.", @@ -56000,6 +56222,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "color": { "description": "Sets the line color.", @@ -57810,6 +58038,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "color": { "description": "Sets the line color.", @@ -59651,6 +59885,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "color": { "description": "Sets the line color.", @@ -61494,6 +61734,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "marker": { "autocolorscale": { "description": "Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `marker.colorscale`. Has an effect only if in `marker.color` is set to a numerical array. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed.", @@ -63646,6 +63892,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "lighting": { "ambient": { "description": "Ambient light increases overall color visibility but can wash out the image.", @@ -64346,6 +64598,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "level": { "anim": true, "description": "Sets the level from which this trace hierarchy is rendered. Set `level` to `''` to start from the root node in the hierarchy. Must be an \"id\" if `ids` is filled in, otherwise plotly attempts to find a matching item in `labels`.", @@ -66262,6 +66520,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "lighting": { "ambient": { "description": "Ambient light increases overall color visibility but can wash out the image.", @@ -67155,6 +67419,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "meta": { "arrayOk": true, "description": "Assigns extra meta information associated with this trace that can be used in various text attributes. Attributes such as trace `name`, graph, axis and colorbar `title.text`, annotation `text` `rangeselector`, `updatemenues` and `sliders` `label` text all support `meta`. To access the trace `meta` values in an attribute in the same trace, simply use `%{meta[i]}` where `i` is the index or key of the `meta` item in question. To access trace `meta` in layout attributes, use `%{data[n[.meta[i]}` where `i` is the index or key of the `meta` and `n` is the trace index.", @@ -67561,6 +67831,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "level": { "anim": true, "description": "Sets the level from which this trace hierarchy is rendered. Set `level` to `''` to start from the root node in the hierarchy. Must be an \"id\" if `ids` is filled in, otherwise plotly attempts to find a matching item in `labels`.", @@ -68878,6 +69154,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "line": { "color": { "description": "Sets the color of line bounding the violin(s).", @@ -70662,6 +70944,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "lighting": { "ambient": { "description": "Ambient light increases overall color visibility but can wash out the image.", @@ -71501,6 +71789,12 @@ "editType": "style", "valType": "number" }, + "legendtextwidth": { + "description": "Sets the width (in px) of the legend for this trace.", + "editType": "style", + "min": 0, + "valType": "number" + }, "measure": { "description": "An array containing types of values. By default the values are considered as 'relative'. However; it is possible to use 'total' to compute the sums. Also 'absolute' could be applied to reset the computed total or to declare an initial value where needed.", "dflt": [], From 083d061468465e3edae4e29ac3a2ae1486069d56 Mon Sep 17 00:00:00 2001 From: nickmelnikov82 Date: Thu, 28 Jul 2022 13:19:09 +0300 Subject: [PATCH 2/6] Allow set legend with in fractions --- src/components/legend/attributes.js | 11 ++++++++-- src/components/legend/defaults.js | 3 ++- src/components/legend/draw.js | 32 ++++++++++++++++++----------- src/plots/attributes.js | 4 ++-- src/plots/plots.js | 2 +- test/jasmine/tests/legend_test.js | 31 ++++++++++++---------------- 6 files changed, 47 insertions(+), 36 deletions(-) diff --git a/src/components/legend/attributes.js b/src/components/legend/attributes.js index 907e7e83059..9e343f00c41 100644 --- a/src/components/legend/attributes.js +++ b/src/components/legend/attributes.js @@ -74,11 +74,18 @@ module.exports = { 'Sets the amount of vertical space (in px) between legend groups.' ].join(' ') }, - legendtextwidth: { + entrywidth: { valType: 'number', min: 0, editType: 'legend', - description: 'Sets the width (in px) of the legend.', + description: 'Sets the width (in px or fraction) of the legend.', + }, + widthmode: { + valType: 'enumerated', + values: ['fraction', 'pixels'], + dflt: 'pixels', + editType: 'legend', + description: 'Determines what entrywidth means.', }, itemsizing: { valType: 'enumerated', diff --git a/src/components/legend/defaults.js b/src/components/legend/defaults.js index 63713a2f3f0..d42502f0b8f 100644 --- a/src/components/legend/defaults.js +++ b/src/components/legend/defaults.js @@ -122,7 +122,8 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) { coerce('traceorder', defaultOrder); if(helpers.isGrouped(layoutOut.legend)) coerce('tracegroupgap'); - coerce('legendtextwidth'); + coerce('entrywidth'); + coerce('widthmode'); coerce('itemsizing'); coerce('itemwidth'); diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index ed440c094e8..a2b9eacadc6 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -351,17 +351,19 @@ function _draw(gd, legendObj) { }], gd); } -function getTraceWidth(trace, legendObj, textGap, isGrouped) { +function getTraceWidth(trace, legendObj, textGap) { var legendItem = trace[0]; var legendWidth = legendItem.width; - if(legendItem.trace.legendtextwidth !== undefined) { - legendWidth = legendItem.trace.legendtextwidth; - } else if(isGrouped && legendItem.trace.legendgroup !== '') { - legendWidth = legendItem.width; - } else if(legendObj.legendtextwidth !== undefined) { - legendWidth = legendObj.legendtextwidth; - } + var traceLegendWidth = legendItem.trace.legendwidth || legendObj.entrywidth + + if (traceLegendWidth) { + if (legendObj.widthmode === "pixels") { + return traceLegendWidth + textGap + } else { + return legendObj._maxWidth * traceLegendWidth + } + } return legendWidth + textGap; } @@ -704,7 +706,7 @@ function computeLegendDimensions(gd, groups, traces, legendObj) { var maxItemWidth = 0; var combinedItemWidth = 0; traces.each(function(d) { - var w = getTraceWidth(d, legendObj, textGap, isGrouped); + var w = getTraceWidth(d, legendObj, textGap); maxItemWidth = Math.max(maxItemWidth, w); combinedItemWidth += w; }); @@ -720,7 +722,7 @@ function computeLegendDimensions(gd, groups, traces, legendObj) { var maxWidthInGroup = 0; var offsetY = 0; d3.select(this).selectAll('g.traces').each(function(d) { - var w = getTraceWidth(d, legendObj, textGap, isGrouped); + var w = getTraceWidth(d, legendObj, textGap); var h = d[0].height; Drawing.setTranslate(this, @@ -768,7 +770,11 @@ function computeLegendDimensions(gd, groups, traces, legendObj) { traces.each(function(d) { var h = d[0].height; var w = getTraceWidth(d, legendObj, textGap, isGrouped); - var next = (oneRowLegend ? w : maxItemWidth) + itemGap; + var next = (oneRowLegend ? w : maxItemWidth); + + if (legendObj.widthmode !== 'fraction') { + next += itemGap; + } if((next + bw + offsetX - itemGap) >= legendObj._maxWidth) { maxRowWidth = Math.max(maxRowWidth, rowWidth); @@ -825,7 +831,9 @@ function computeLegendDimensions(gd, groups, traces, legendObj) { traceWidth = legendGroupWidths[legendgroup]; } var w = isEditable ? textGap : (toggleRectWidth || traceWidth); - if(!isVertical) w += itemGap / 2; + if(!isVertical && legendObj.widthmode !== "fraction") { + w += itemGap / 2; + } Drawing.setRect(traceToggle, 0, -h / 2, w, h); }); } diff --git a/src/plots/attributes.js b/src/plots/attributes.js index 3653a5c03f7..9f9952cbfc5 100644 --- a/src/plots/attributes.js +++ b/src/plots/attributes.js @@ -72,11 +72,11 @@ module.exports = { 'and ranks greater than 1000 to go after all unranked items.' ].join(' ') }, - legendtextwidth: { + legendwidth: { valType: 'number', min: 0, editType: 'style', - description: 'Sets the width (in px) of the legend for this trace.', + description: 'Sets the width (in px or fraction) of the legend for this trace.', }, opacity: { valType: 'number', diff --git a/src/plots/plots.js b/src/plots/plots.js index 371dc14bfc5..a29f912092d 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -1320,7 +1320,7 @@ plots.supplyTraceDefaults = function(traceIn, traceOut, colorIndex, layout, trac 'showlegend' ); - coerce('legendtextwidth'); + coerce('legendwidth'); coerce('legendgroup'); coerce('legendgrouptitle.text'); coerce('legendrank'); diff --git a/test/jasmine/tests/legend_test.js b/test/jasmine/tests/legend_test.js index a198c9bbfbb..f15471fbd64 100644 --- a/test/jasmine/tests/legend_test.js +++ b/test/jasmine/tests/legend_test.js @@ -2347,7 +2347,7 @@ describe('legend with custom doubleClickDelay', function() { }, 3 * jasmine.DEFAULT_TIMEOUT_INTERVAL); }); -describe('legend with custom legendtextwidth', function() { +describe('legend with custom legendwidth', function() { var gd; var data = [ @@ -2379,10 +2379,10 @@ describe('legend with custom legendtextwidth', function() { }); } - it('should change width when trace has legendtextwidth', function(done) { + it('should change width when trace has legendwidth', function(done) { var extendedData = Lib.extendDeep([], data); extendedData.forEach(function(trace, index) { - trace.legendtextwidth = (index + 1) * 50; + trace.legendwidth = (index + 1) * 50; }); var textGap = 30 + constants.itemGap * 2 + constants.itemGap / 2; @@ -2392,10 +2392,10 @@ describe('legend with custom legendtextwidth', function() { }).then(done); }); - it('should change width when legend has legendtextwidth', function(done) { + it('should change width when legend has entrywidth', function(done) { var extendedLayout = Lib.extendDeep([], layout); var width = 50; - extendedLayout.legend.legendtextwidth = width; + extendedLayout.legend.entrywidth = width; var textGap = 30 + constants.itemGap * 2 + constants.itemGap / 2; @@ -2404,12 +2404,12 @@ describe('legend with custom legendtextwidth', function() { }).then(done); }); - it('should change group width when trace has legendtextwidth', function(done) { + it('should change group width when trace has legendwidth', function(done) { var extendedLayout = Lib.extendDeep([], layout); extendedLayout.legend.traceorder = 'grouped'; var extendedData = Lib.extendDeep([], data); - extendedData[0].legendtextwidth = 100; + extendedData[0].legendwidth = 100; extendedData[0].legendgroup = 'test'; extendedData[1].legendgroup = 'test'; @@ -2420,20 +2420,15 @@ describe('legend with custom legendtextwidth', function() { }).then(done); }); - it('should prefer group legendtextwidth to the legend legendtextwidth', function(done) { - var extendedLayout = Lib.extendDeep([], layout); - extendedLayout.legend.traceorder = 'grouped'; - extendedLayout.legend.legendtextwidth = 50; - var extendedData = Lib.extendDeep([], data); - extendedData[0].legendtextwidth = 100; - extendedData[0].legendgroup = 'test'; - extendedData[1].legendgroup = 'test'; - var textGap = 30 + constants.itemGap * 2 + constants.itemGap / 2; + it('should change width when legend has entrywidth and widthmode is fraction', function(done) { + var extendedLayout = Lib.extendDeep([], layout); + extendedLayout.legend.widthmode = 'fraction'; + extendedLayout.legend.entrywidth = 0.3; - Plotly.newPlot(gd, {data: extendedData, layout: extendedLayout}).then(function() { - assertLegendTextWidth([100 + textGap, 100 + textGap, 50 + textGap]); + Plotly.newPlot(gd, {data: data, layout: extendedLayout}).then(function() { + assertLegendTextWidth([162, 162, 162]); }).then(done); }); }); From 4c1a865cdb0faaa489a0fdd5342063ccdec35eac Mon Sep 17 00:00:00 2001 From: nickmelnikov82 Date: Thu, 28 Jul 2022 13:22:44 +0300 Subject: [PATCH 3/6] Regenerate schema --- test/plot-schema.json | 214 ++++++++++++++++++++++-------------------- 1 file changed, 112 insertions(+), 102 deletions(-) diff --git a/test/plot-schema.json b/test/plot-schema.json index 3c3f49e7205..87715ce207c 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -2750,6 +2750,12 @@ "valType": "number" }, "editType": "legend", + "entrywidth": { + "description": "Sets the width (in px or fraction) of the legend.", + "editType": "legend", + "min": 0, + "valType": "number" + }, "font": { "color": { "editType": "legend", @@ -2841,12 +2847,6 @@ "min": 30, "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend.", - "editType": "legend", - "min": 0, - "valType": "number" - }, "orientation": { "description": "Sets the orientation of the legend.", "dflt": "v", @@ -2934,6 +2934,16 @@ "bottom" ] }, + "widthmode": { + "description": "Determines what entrywidth means.", + "dflt": "pixels", + "editType": "legend", + "valType": "enumerated", + "values": [ + "fraction", + "pixels" + ] + }, "x": { "description": "Sets the x position (in normalized coordinates) of the legend. Defaults to *1.02* for vertical legends and defaults to *0* for horizontal legends.", "editType": "legend", @@ -12616,8 +12626,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -14137,8 +14147,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -15437,8 +15447,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -16762,8 +16772,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -18264,8 +18274,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -19118,8 +19128,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -20111,8 +20121,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -21133,8 +21143,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -22331,8 +22341,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -23575,8 +23585,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -24530,8 +24540,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -25067,8 +25077,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -26494,8 +26504,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -27570,8 +27580,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -28701,8 +28711,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -29494,8 +29504,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -31452,8 +31462,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -32718,8 +32728,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -33475,8 +33485,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -34690,8 +34700,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -35555,8 +35565,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -36588,8 +36598,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -37871,8 +37881,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -38499,8 +38509,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -38998,8 +39008,8 @@ "valType": "string" } }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -39961,8 +39971,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -41162,8 +41172,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -41760,8 +41770,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -42224,8 +42234,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -43419,8 +43429,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -45682,8 +45692,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -47671,8 +47681,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -49498,8 +49508,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -51504,8 +51514,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -53409,8 +53419,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -54580,8 +54590,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -56429,8 +56439,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -58245,8 +58255,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -60092,8 +60102,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -61941,8 +61951,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -64099,8 +64109,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -64805,8 +64815,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -66727,8 +66737,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -67626,8 +67636,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -68038,8 +68048,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -69361,8 +69371,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -71151,8 +71161,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" @@ -71996,8 +72006,8 @@ "editType": "style", "valType": "number" }, - "legendtextwidth": { - "description": "Sets the width (in px) of the legend for this trace.", + "legendwidth": { + "description": "Sets the width (in px or fraction) of the legend for this trace.", "editType": "style", "min": 0, "valType": "number" From 05b6d77a29307d1e69c515e88551351c41ae17a7 Mon Sep 17 00:00:00 2001 From: nickmelnikov82 Date: Thu, 28 Jul 2022 15:46:02 +0300 Subject: [PATCH 4/6] Fix syntax --- src/components/legend/draw.js | 18 +++++++++--------- test/jasmine/tests/legend_test.js | 2 -- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index a2b9eacadc6..44279f73749 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -355,15 +355,15 @@ function getTraceWidth(trace, legendObj, textGap) { var legendItem = trace[0]; var legendWidth = legendItem.width; - var traceLegendWidth = legendItem.trace.legendwidth || legendObj.entrywidth + var traceLegendWidth = legendItem.trace.legendwidth || legendObj.entrywidth; - if (traceLegendWidth) { - if (legendObj.widthmode === "pixels") { - return traceLegendWidth + textGap - } else { - return legendObj._maxWidth * traceLegendWidth - } + if(traceLegendWidth) { + if(legendObj.widthmode === 'pixels') { + return traceLegendWidth + textGap; + } else { + return legendObj._maxWidth * traceLegendWidth; } + } return legendWidth + textGap; } @@ -772,7 +772,7 @@ function computeLegendDimensions(gd, groups, traces, legendObj) { var w = getTraceWidth(d, legendObj, textGap, isGrouped); var next = (oneRowLegend ? w : maxItemWidth); - if (legendObj.widthmode !== 'fraction') { + if(legendObj.widthmode !== 'fraction') { next += itemGap; } @@ -831,7 +831,7 @@ function computeLegendDimensions(gd, groups, traces, legendObj) { traceWidth = legendGroupWidths[legendgroup]; } var w = isEditable ? textGap : (toggleRectWidth || traceWidth); - if(!isVertical && legendObj.widthmode !== "fraction") { + if(!isVertical && legendObj.widthmode !== 'fraction') { w += itemGap / 2; } Drawing.setRect(traceToggle, 0, -h / 2, w, h); diff --git a/test/jasmine/tests/legend_test.js b/test/jasmine/tests/legend_test.js index f15471fbd64..f36a90b05cc 100644 --- a/test/jasmine/tests/legend_test.js +++ b/test/jasmine/tests/legend_test.js @@ -2420,8 +2420,6 @@ describe('legend with custom legendwidth', function() { }).then(done); }); - - it('should change width when legend has entrywidth and widthmode is fraction', function(done) { var extendedLayout = Lib.extendDeep([], layout); extendedLayout.legend.widthmode = 'fraction'; From 10d9d8e05fbc83bd5d2b045d6c541e9cb0da5604 Mon Sep 17 00:00:00 2001 From: nickmelnikov82 Date: Mon, 8 Aug 2022 17:55:33 +0300 Subject: [PATCH 5/6] Rename widhmode with entrywidthmode --- src/components/legend/attributes.js | 2 +- src/components/legend/defaults.js | 2 +- src/components/legend/draw.js | 6 +++--- test/jasmine/tests/legend_test.js | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/legend/attributes.js b/src/components/legend/attributes.js index 9e343f00c41..f0a94879862 100644 --- a/src/components/legend/attributes.js +++ b/src/components/legend/attributes.js @@ -80,7 +80,7 @@ module.exports = { editType: 'legend', description: 'Sets the width (in px or fraction) of the legend.', }, - widthmode: { + entrywidthmode: { valType: 'enumerated', values: ['fraction', 'pixels'], dflt: 'pixels', diff --git a/src/components/legend/defaults.js b/src/components/legend/defaults.js index d42502f0b8f..a2bfc776848 100644 --- a/src/components/legend/defaults.js +++ b/src/components/legend/defaults.js @@ -123,7 +123,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) { if(helpers.isGrouped(layoutOut.legend)) coerce('tracegroupgap'); coerce('entrywidth'); - coerce('widthmode'); + coerce('entrywidthmode'); coerce('itemsizing'); coerce('itemwidth'); diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index 44279f73749..11f81d2185c 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -358,7 +358,7 @@ function getTraceWidth(trace, legendObj, textGap) { var traceLegendWidth = legendItem.trace.legendwidth || legendObj.entrywidth; if(traceLegendWidth) { - if(legendObj.widthmode === 'pixels') { + if(legendObj.entrywidthmode === 'pixels') { return traceLegendWidth + textGap; } else { return legendObj._maxWidth * traceLegendWidth; @@ -772,7 +772,7 @@ function computeLegendDimensions(gd, groups, traces, legendObj) { var w = getTraceWidth(d, legendObj, textGap, isGrouped); var next = (oneRowLegend ? w : maxItemWidth); - if(legendObj.widthmode !== 'fraction') { + if(legendObj.entrywidthmode !== 'fraction') { next += itemGap; } @@ -831,7 +831,7 @@ function computeLegendDimensions(gd, groups, traces, legendObj) { traceWidth = legendGroupWidths[legendgroup]; } var w = isEditable ? textGap : (toggleRectWidth || traceWidth); - if(!isVertical && legendObj.widthmode !== 'fraction') { + if(!isVertical && legendObj.entrywidthmode !== 'fraction') { w += itemGap / 2; } Drawing.setRect(traceToggle, 0, -h / 2, w, h); diff --git a/test/jasmine/tests/legend_test.js b/test/jasmine/tests/legend_test.js index f36a90b05cc..2a68e6b753a 100644 --- a/test/jasmine/tests/legend_test.js +++ b/test/jasmine/tests/legend_test.js @@ -2420,9 +2420,9 @@ describe('legend with custom legendwidth', function() { }).then(done); }); - it('should change width when legend has entrywidth and widthmode is fraction', function(done) { + it('should change width when legend has entrywidth and entrywidthmode is fraction', function(done) { var extendedLayout = Lib.extendDeep([], layout); - extendedLayout.legend.widthmode = 'fraction'; + extendedLayout.legend.entrywidthmode = 'fraction'; extendedLayout.legend.entrywidth = 0.3; Plotly.newPlot(gd, {data: data, layout: extendedLayout}).then(function() { From 08cb09805b8b2167689ff1caa73820731f039cb4 Mon Sep 17 00:00:00 2001 From: nickmelnikov82 Date: Mon, 8 Aug 2022 18:12:36 +0300 Subject: [PATCH 6/6] Commit schema --- test/plot-schema.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/plot-schema.json b/test/plot-schema.json index 87715ce207c..2eca862f6b2 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -2756,6 +2756,16 @@ "min": 0, "valType": "number" }, + "entrywidthmode": { + "description": "Determines what entrywidth means.", + "dflt": "pixels", + "editType": "legend", + "valType": "enumerated", + "values": [ + "fraction", + "pixels" + ] + }, "font": { "color": { "editType": "legend", @@ -2934,16 +2944,6 @@ "bottom" ] }, - "widthmode": { - "description": "Determines what entrywidth means.", - "dflt": "pixels", - "editType": "legend", - "valType": "enumerated", - "values": [ - "fraction", - "pixels" - ] - }, "x": { "description": "Sets the x position (in normalized coordinates) of the legend. Defaults to *1.02* for vertical legends and defaults to *0* for horizontal legends.", "editType": "legend",