From b0ac05f1cc00f6b19b840670d5e3ea5a9c8b08af Mon Sep 17 00:00:00 2001 From: Paul Brussee Date: Thu, 29 Jul 2021 01:00:47 +0200 Subject: [PATCH 1/7] add legend.groupclick option toggle individual items in a legendgroup or the legendgroup as a whole --- src/components/legend/attributes.js | 19 ++++++++++++++----- src/components/legend/defaults.js | 1 + src/components/legend/handle_click.js | 20 +++++++++++++++----- test/plot-schema.json | 15 +++++++++++++-- 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/components/legend/attributes.js b/src/components/legend/attributes.js index 28a3d00fd25..7d713557bf6 100644 --- a/src/components/legend/attributes.js +++ b/src/components/legend/attributes.js @@ -84,7 +84,6 @@ module.exports = { editType: 'legend', description: 'Sets the width (in px) of the legend item symbols (the part other than the title.text).', }, - itemclick: { valType: 'enumerated', values: ['toggle', 'toggleothers', false], @@ -94,7 +93,7 @@ module.exports = { 'Determines the behavior on legend item click.', '*toggle* toggles the visibility of the item clicked on the graph.', '*toggleothers* makes the clicked item the sole visible item on the graph.', - '*false* disable legend item click interactions.' + '*false* disables legend item click interactions.' ].join(' ') }, itemdoubleclick: { @@ -106,10 +105,21 @@ module.exports = { 'Determines the behavior on legend item double-click.', '*toggle* toggles the visibility of the item clicked on the graph.', '*toggleothers* makes the clicked item the sole visible item on the graph.', - '*false* disable legend item double-click interactions.' + '*false* disables legend item double-click interactions.' + ].join(' ') + }, + groupclick: { + valType: 'enumerated', + values: ['toggleitem', 'togglegroup', false], + dflt: 'togglegroup', + editType: 'legend', + description: [ + 'Determines the behavior on legend group item click.', + '*toggleitem* toggles the visibility of the individual item clicked on the graph.', + '*togglegroup* toggles the visibility of all items in the same legendgroup as the item clicked on the graph.', + '*false* disables legend group click interactions.' ].join(' ') }, - x: { valType: 'number', min: -2, @@ -208,6 +218,5 @@ module.exports = { }, editType: 'legend', }, - editType: 'legend' }; diff --git a/src/components/legend/defaults.js b/src/components/legend/defaults.js index e74575f45de..7862a631956 100644 --- a/src/components/legend/defaults.js +++ b/src/components/legend/defaults.js @@ -110,6 +110,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) { coerce('itemclick'); coerce('itemdoubleclick'); + coerce('groupclick'); coerce('x', defaultX); coerce('xanchor'); diff --git a/src/components/legend/handle_click.js b/src/components/legend/handle_click.js index f2b21412f04..54dea19b699 100644 --- a/src/components/legend/handle_click.js +++ b/src/components/legend/handle_click.js @@ -12,6 +12,7 @@ module.exports = function handleClick(g, gd, numClicks) { var itemClick = fullLayout.legend.itemclick; var itemDoubleClick = fullLayout.legend.itemdoubleclick; + var groupClick = fullLayout.legend.groupclick; if(numClicks === 1 && itemClick === 'toggle' && itemDoubleClick === 'toggleothers' && SHOWISOLATETIP && gd.data && gd._context.showTips @@ -27,6 +28,8 @@ module.exports = function handleClick(g, gd, numClicks) { else if(numClicks === 2) mode = itemDoubleClick; if(!mode) return; + var toggleGroup = groupClick === undefined || groupClick === 'togglegroup'; + var hiddenSlices = fullLayout.hiddenlabels ? fullLayout.hiddenlabels.slice() : []; @@ -148,10 +151,16 @@ module.exports = function handleClick(g, gd, numClicks) { } if(hasLegendgroup) { - for(i = 0; i < fullData.length; i++) { - if(fullData[i].visible !== false && fullData[i].legendgroup === legendgroup) { - setVisibility(fullData[i], nextVisibility); + if(groupClick === false) return; + + if(toggleGroup) { + for(i = 0; i < fullData.length; i++) { + if(fullData[i].visible !== false && fullData[i].legendgroup === legendgroup) { + setVisibility(fullData[i], nextVisibility); + } } + } else { + setVisibility(fullTrace, nextVisibility); } } else { setVisibility(fullTrace, nextVisibility); @@ -192,7 +201,8 @@ module.exports = function handleClick(g, gd, numClicks) { // N.B. consider traces that have a set legendgroup as toggleable notInLegend = (fullData[i].showlegend !== true && !fullData[i].legendgroup); isInGroup = isClicked || (hasLegendgroup && fullData[i].legendgroup === legendgroup); - setVisibility(fullData[i], (isInGroup || notInLegend) ? true : otherState); + if(isInGroup && groupClick === false) continue; + setVisibility(fullData[i], ((isInGroup && toggleGroup) || notInLegend) ? true : otherState); break; } } @@ -219,7 +229,7 @@ module.exports = function handleClick(g, gd, numClicks) { for(i = 0; i < keys.length; i++) { key = keys[i]; for(j = 0; j < attrIndices.length; j++) { - // Use hasOwnPropety to protect against falsey values: + // Use hasOwnProperty to protect against falsy values: if(!attrUpdate[key].hasOwnProperty(j)) { attrUpdate[key][j] = undefined; } diff --git a/test/plot-schema.json b/test/plot-schema.json index 772e34b2e65..9284a41c00c 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -2683,8 +2683,19 @@ "valType": "number" } }, + "groupclick": { + "description": "Determines the behavior on legend group item click. *toggleitem* toggles the visibility of the individual item clicked on the graph. *togglegroup* toggles the visibility of all items in the same legendgroup as the item clicked on the graph. *false* disables legend group click interactions.", + "dflt": "togglegroup", + "editType": "legend", + "valType": "enumerated", + "values": [ + "toggleitem", + "togglegroup", + false + ] + }, "itemclick": { - "description": "Determines the behavior on legend item click. *toggle* toggles the visibility of the item clicked on the graph. *toggleothers* makes the clicked item the sole visible item on the graph. *false* disable legend item click interactions.", + "description": "Determines the behavior on legend item click. *toggle* toggles the visibility of the item clicked on the graph. *toggleothers* makes the clicked item the sole visible item on the graph. *false* disables legend item click interactions.", "dflt": "toggle", "editType": "legend", "valType": "enumerated", @@ -2695,7 +2706,7 @@ ] }, "itemdoubleclick": { - "description": "Determines the behavior on legend item double-click. *toggle* toggles the visibility of the item clicked on the graph. *toggleothers* makes the clicked item the sole visible item on the graph. *false* disable legend item double-click interactions.", + "description": "Determines the behavior on legend item double-click. *toggle* toggles the visibility of the item clicked on the graph. *toggleothers* makes the clicked item the sole visible item on the graph. *false* disables legend item double-click interactions.", "dflt": "toggleothers", "editType": "legend", "valType": "enumerated", From 7bc5887e196f40730febbf04e0f157ab73583cf2 Mon Sep 17 00:00:00 2001 From: archmoj Date: Wed, 25 Aug 2021 13:53:26 -0400 Subject: [PATCH 2/7] no false option for groupclick --- src/components/legend/attributes.js | 5 ++--- src/components/legend/handle_click.js | 3 --- test/plot-schema.json | 5 ++--- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/components/legend/attributes.js b/src/components/legend/attributes.js index 7d713557bf6..e5713595d39 100644 --- a/src/components/legend/attributes.js +++ b/src/components/legend/attributes.js @@ -110,14 +110,13 @@ module.exports = { }, groupclick: { valType: 'enumerated', - values: ['toggleitem', 'togglegroup', false], + values: ['toggleitem', 'togglegroup'], dflt: 'togglegroup', editType: 'legend', description: [ 'Determines the behavior on legend group item click.', '*toggleitem* toggles the visibility of the individual item clicked on the graph.', - '*togglegroup* toggles the visibility of all items in the same legendgroup as the item clicked on the graph.', - '*false* disables legend group click interactions.' + '*togglegroup* toggles the visibility of all items in the same legendgroup as the item clicked on the graph.' ].join(' ') }, x: { diff --git a/src/components/legend/handle_click.js b/src/components/legend/handle_click.js index 54dea19b699..1e3bedf94cc 100644 --- a/src/components/legend/handle_click.js +++ b/src/components/legend/handle_click.js @@ -151,8 +151,6 @@ module.exports = function handleClick(g, gd, numClicks) { } if(hasLegendgroup) { - if(groupClick === false) return; - if(toggleGroup) { for(i = 0; i < fullData.length; i++) { if(fullData[i].visible !== false && fullData[i].legendgroup === legendgroup) { @@ -201,7 +199,6 @@ module.exports = function handleClick(g, gd, numClicks) { // N.B. consider traces that have a set legendgroup as toggleable notInLegend = (fullData[i].showlegend !== true && !fullData[i].legendgroup); isInGroup = isClicked || (hasLegendgroup && fullData[i].legendgroup === legendgroup); - if(isInGroup && groupClick === false) continue; setVisibility(fullData[i], ((isInGroup && toggleGroup) || notInLegend) ? true : otherState); break; } diff --git a/test/plot-schema.json b/test/plot-schema.json index 9284a41c00c..5cb02325f61 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -2684,14 +2684,13 @@ } }, "groupclick": { - "description": "Determines the behavior on legend group item click. *toggleitem* toggles the visibility of the individual item clicked on the graph. *togglegroup* toggles the visibility of all items in the same legendgroup as the item clicked on the graph. *false* disables legend group click interactions.", + "description": "Determines the behavior on legend group item click. *toggleitem* toggles the visibility of the individual item clicked on the graph. *togglegroup* toggles the visibility of all items in the same legendgroup as the item clicked on the graph.", "dflt": "togglegroup", "editType": "legend", "valType": "enumerated", "values": [ "toggleitem", - "togglegroup", - false + "togglegroup" ] }, "itemclick": { From 3e3ee1e9a427ae685f825e5aaa2ded34d5c88905 Mon Sep 17 00:00:00 2001 From: archmoj Date: Wed, 25 Aug 2021 13:54:45 -0400 Subject: [PATCH 3/7] no undefined groupclick --- src/components/legend/handle_click.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/legend/handle_click.js b/src/components/legend/handle_click.js index 1e3bedf94cc..cdde3ce01ff 100644 --- a/src/components/legend/handle_click.js +++ b/src/components/legend/handle_click.js @@ -28,7 +28,7 @@ module.exports = function handleClick(g, gd, numClicks) { else if(numClicks === 2) mode = itemDoubleClick; if(!mode) return; - var toggleGroup = groupClick === undefined || groupClick === 'togglegroup'; + var toggleGroup = groupClick === 'togglegroup'; var hiddenSlices = fullLayout.hiddenlabels ? fullLayout.hiddenlabels.slice() : From dc6ce6d0a2df7fed86f81b77d5fcdd81b43cc1a1 Mon Sep 17 00:00:00 2001 From: archmoj Date: Wed, 25 Aug 2021 14:13:23 -0400 Subject: [PATCH 4/7] log for PR 5849 --- draftlogs/5849_add.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 draftlogs/5849_add.md diff --git a/draftlogs/5849_add.md b/draftlogs/5849_add.md new file mode 100644 index 00000000000..dd68748b66c --- /dev/null +++ b/draftlogs/5849_add.md @@ -0,0 +1,2 @@ + - Add `legend.groupclick` options [[#5849](https://github.com/plotly/plotly.js/pull/5849)], + with thanks to @rlreamy for the contribution! \ No newline at end of file From f97300e294f51a499c8fe7a1fb49633fd575756b Mon Sep 17 00:00:00 2001 From: archmoj Date: Wed, 25 Aug 2021 14:19:18 -0400 Subject: [PATCH 5/7] keep gorup titles visible when groupclick is set to toggleitem --- src/components/legend/get_legend_data.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/legend/get_legend_data.js b/src/components/legend/get_legend_data.js index 202064202a1..a19d582b536 100644 --- a/src/components/legend/get_legend_data.js +++ b/src/components/legend/get_legend_data.js @@ -152,7 +152,7 @@ module.exports = function getLegendData(calcdata, opts) { trace: { showlegend: firstItemTrace.showlegend, legendgroup: firstItemTrace.legendgroup, - visible: firstItemTrace.visible + visible: opts.groupclick === 'toggleitem' ? true : firstItemTrace.visible } }); } From 363b1c4f2a5cf6742bc2e08070e437fabe3c00d2 Mon Sep 17 00:00:00 2001 From: archmoj Date: Wed, 25 Aug 2021 14:43:57 -0400 Subject: [PATCH 6/7] add jasmine test --- test/jasmine/tests/legend_test.js | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/test/jasmine/tests/legend_test.js b/test/jasmine/tests/legend_test.js index 054d2e36b07..f1c71c12bd3 100644 --- a/test/jasmine/tests/legend_test.js +++ b/test/jasmine/tests/legend_test.js @@ -1782,6 +1782,49 @@ describe('legend interaction', function() { }); }); + describe('legendgroup visibility case of groupclick: "toggleitem"', function() { + beforeEach(function(done) { + Plotly.newPlot(gd, [{ + x: [1, 2], + y: [3, 4], + visible: false + }, { + x: [1, 2, 3, 4], + y: [0, 1, 2, 3], + legendgroup: 'foo' + }, { + x: [1, 2, 3, 4], + y: [1, 3, 2, 4], + }, { + x: [1, 2, 3, 4], + y: [1, 3, 2, 4], + legendgroup: 'foo' + }], { + legend: { + groupclick: 'toggleitem' + } + }).then(done); + }); + + it('toggles visibilities', function(done) { + Promise.resolve() + .then(assertVisible([false, true, true, true])) + .then(click(0)) + .then(assertVisible([false, 'legendonly', true, true])) + .then(click(0)) + .then(assertVisible([false, true, true, true])) + .then(click(1)) + .then(assertVisible([false, true, true, 'legendonly'])) + .then(click(1)) + .then(assertVisible([false, true, true, true])) + .then(click(2)) + .then(assertVisible([false, true, 'legendonly', true])) + .then(click(2)) + .then(assertVisible([false, true, true, true])) + .then(done, done.fail); + }); + }); + describe('legend visibility toggles with groupby', function() { beforeEach(function(done) { Plotly.newPlot(gd, [{ From e392f79ff790ab5dee584eae720bbf58932985df Mon Sep 17 00:00:00 2001 From: archmoj Date: Wed, 25 Aug 2021 14:58:28 -0400 Subject: [PATCH 7/7] update PR log --- draftlogs/5849_add.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/draftlogs/5849_add.md b/draftlogs/5849_add.md index dd68748b66c..68c2ca0aa0e 100644 --- a/draftlogs/5849_add.md +++ b/draftlogs/5849_add.md @@ -1,2 +1,2 @@ - - Add `legend.groupclick` options [[#5849](https://github.com/plotly/plotly.js/pull/5849)], - with thanks to @rlreamy for the contribution! \ No newline at end of file + - Add `legend.groupclick` options [[#5849](https://github.com/plotly/plotly.js/pull/5849), [#5906](https://github.com/plotly/plotly.js/pull/5906)], + with thanks to @brussee for the contribution! \ No newline at end of file