Skip to content

Add legend.groupclick options to toggle single item within a group #5906

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Aug 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions draftlogs/5849_add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- 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!
18 changes: 13 additions & 5 deletions src/components/legend/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand All @@ -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: {
Expand All @@ -106,10 +105,20 @@ 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'],
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.'
].join(' ')
},

x: {
valType: 'number',
min: -2,
Expand Down Expand Up @@ -208,6 +217,5 @@ module.exports = {
},
editType: 'legend',
},

editType: 'legend'
};
1 change: 1 addition & 0 deletions src/components/legend/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {

coerce('itemclick');
coerce('itemdoubleclick');
coerce('groupclick');

coerce('x', defaultX);
coerce('xanchor');
Expand Down
2 changes: 1 addition & 1 deletion src/components/legend/get_legend_data.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
});
}
Expand Down
17 changes: 12 additions & 5 deletions src/components/legend/handle_click.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -27,6 +28,8 @@ module.exports = function handleClick(g, gd, numClicks) {
else if(numClicks === 2) mode = itemDoubleClick;
if(!mode) return;

var toggleGroup = groupClick === 'togglegroup';

var hiddenSlices = fullLayout.hiddenlabels ?
fullLayout.hiddenlabels.slice() :
[];
Expand Down Expand Up @@ -148,10 +151,14 @@ 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(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);
Expand Down Expand Up @@ -192,7 +199,7 @@ 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);
setVisibility(fullData[i], ((isInGroup && toggleGroup) || notInLegend) ? true : otherState);
break;
}
}
Expand All @@ -219,7 +226,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;
}
Expand Down
43 changes: 43 additions & 0 deletions test/jasmine/tests/legend_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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, [{
Expand Down
14 changes: 12 additions & 2 deletions test/plot-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2683,8 +2683,18 @@
"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.",
"dflt": "togglegroup",
"editType": "legend",
"valType": "enumerated",
"values": [
"toggleitem",
"togglegroup"
]
},
"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",
Expand All @@ -2695,7 +2705,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",
Expand Down