Skip to content

Commit

Permalink
Merge pull request #5906 from plotly/pull-5849
Browse files Browse the repository at this point in the history
Add `legend.groupclick` options to toggle single item within a group
  • Loading branch information
archmoj committed Aug 26, 2021
2 parents c5afe3c + e392f79 commit 164d760
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 13 deletions.
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

0 comments on commit 164d760

Please sign in to comment.