Skip to content

Commit 164d760

Browse files
authored
Merge pull request #5906 from plotly/pull-5849
Add `legend.groupclick` options to toggle single item within a group
2 parents c5afe3c + e392f79 commit 164d760

File tree

7 files changed

+84
-13
lines changed

7 files changed

+84
-13
lines changed

draftlogs/5849_add.md

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- Add `legend.groupclick` options [[#5849](https://github.com/plotly/plotly.js/pull/5849), [#5906](https://github.com/plotly/plotly.js/pull/5906)],
2+
with thanks to @brussee for the contribution!

src/components/legend/attributes.js

+13-5
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ module.exports = {
8484
editType: 'legend',
8585
description: 'Sets the width (in px) of the legend item symbols (the part other than the title.text).',
8686
},
87-
8887
itemclick: {
8988
valType: 'enumerated',
9089
values: ['toggle', 'toggleothers', false],
@@ -94,7 +93,7 @@ module.exports = {
9493
'Determines the behavior on legend item click.',
9594
'*toggle* toggles the visibility of the item clicked on the graph.',
9695
'*toggleothers* makes the clicked item the sole visible item on the graph.',
97-
'*false* disable legend item click interactions.'
96+
'*false* disables legend item click interactions.'
9897
].join(' ')
9998
},
10099
itemdoubleclick: {
@@ -106,10 +105,20 @@ module.exports = {
106105
'Determines the behavior on legend item double-click.',
107106
'*toggle* toggles the visibility of the item clicked on the graph.',
108107
'*toggleothers* makes the clicked item the sole visible item on the graph.',
109-
'*false* disable legend item double-click interactions.'
108+
'*false* disables legend item double-click interactions.'
109+
].join(' ')
110+
},
111+
groupclick: {
112+
valType: 'enumerated',
113+
values: ['toggleitem', 'togglegroup'],
114+
dflt: 'togglegroup',
115+
editType: 'legend',
116+
description: [
117+
'Determines the behavior on legend group item click.',
118+
'*toggleitem* toggles the visibility of the individual item clicked on the graph.',
119+
'*togglegroup* toggles the visibility of all items in the same legendgroup as the item clicked on the graph.'
110120
].join(' ')
111121
},
112-
113122
x: {
114123
valType: 'number',
115124
min: -2,
@@ -208,6 +217,5 @@ module.exports = {
208217
},
209218
editType: 'legend',
210219
},
211-
212220
editType: 'legend'
213221
};

src/components/legend/defaults.js

+1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) {
110110

111111
coerce('itemclick');
112112
coerce('itemdoubleclick');
113+
coerce('groupclick');
113114

114115
coerce('x', defaultX);
115116
coerce('xanchor');

src/components/legend/get_legend_data.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ module.exports = function getLegendData(calcdata, opts) {
152152
trace: {
153153
showlegend: firstItemTrace.showlegend,
154154
legendgroup: firstItemTrace.legendgroup,
155-
visible: firstItemTrace.visible
155+
visible: opts.groupclick === 'toggleitem' ? true : firstItemTrace.visible
156156
}
157157
});
158158
}

src/components/legend/handle_click.js

+12-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module.exports = function handleClick(g, gd, numClicks) {
1212

1313
var itemClick = fullLayout.legend.itemclick;
1414
var itemDoubleClick = fullLayout.legend.itemdoubleclick;
15+
var groupClick = fullLayout.legend.groupclick;
1516

1617
if(numClicks === 1 && itemClick === 'toggle' && itemDoubleClick === 'toggleothers' &&
1718
SHOWISOLATETIP && gd.data && gd._context.showTips
@@ -27,6 +28,8 @@ module.exports = function handleClick(g, gd, numClicks) {
2728
else if(numClicks === 2) mode = itemDoubleClick;
2829
if(!mode) return;
2930

31+
var toggleGroup = groupClick === 'togglegroup';
32+
3033
var hiddenSlices = fullLayout.hiddenlabels ?
3134
fullLayout.hiddenlabels.slice() :
3235
[];
@@ -148,10 +151,14 @@ module.exports = function handleClick(g, gd, numClicks) {
148151
}
149152

150153
if(hasLegendgroup) {
151-
for(i = 0; i < fullData.length; i++) {
152-
if(fullData[i].visible !== false && fullData[i].legendgroup === legendgroup) {
153-
setVisibility(fullData[i], nextVisibility);
154+
if(toggleGroup) {
155+
for(i = 0; i < fullData.length; i++) {
156+
if(fullData[i].visible !== false && fullData[i].legendgroup === legendgroup) {
157+
setVisibility(fullData[i], nextVisibility);
158+
}
154159
}
160+
} else {
161+
setVisibility(fullTrace, nextVisibility);
155162
}
156163
} else {
157164
setVisibility(fullTrace, nextVisibility);
@@ -192,7 +199,7 @@ module.exports = function handleClick(g, gd, numClicks) {
192199
// N.B. consider traces that have a set legendgroup as toggleable
193200
notInLegend = (fullData[i].showlegend !== true && !fullData[i].legendgroup);
194201
isInGroup = isClicked || (hasLegendgroup && fullData[i].legendgroup === legendgroup);
195-
setVisibility(fullData[i], (isInGroup || notInLegend) ? true : otherState);
202+
setVisibility(fullData[i], ((isInGroup && toggleGroup) || notInLegend) ? true : otherState);
196203
break;
197204
}
198205
}
@@ -219,7 +226,7 @@ module.exports = function handleClick(g, gd, numClicks) {
219226
for(i = 0; i < keys.length; i++) {
220227
key = keys[i];
221228
for(j = 0; j < attrIndices.length; j++) {
222-
// Use hasOwnPropety to protect against falsey values:
229+
// Use hasOwnProperty to protect against falsy values:
223230
if(!attrUpdate[key].hasOwnProperty(j)) {
224231
attrUpdate[key][j] = undefined;
225232
}

test/jasmine/tests/legend_test.js

+43
Original file line numberDiff line numberDiff line change
@@ -1782,6 +1782,49 @@ describe('legend interaction', function() {
17821782
});
17831783
});
17841784

1785+
describe('legendgroup visibility case of groupclick: "toggleitem"', function() {
1786+
beforeEach(function(done) {
1787+
Plotly.newPlot(gd, [{
1788+
x: [1, 2],
1789+
y: [3, 4],
1790+
visible: false
1791+
}, {
1792+
x: [1, 2, 3, 4],
1793+
y: [0, 1, 2, 3],
1794+
legendgroup: 'foo'
1795+
}, {
1796+
x: [1, 2, 3, 4],
1797+
y: [1, 3, 2, 4],
1798+
}, {
1799+
x: [1, 2, 3, 4],
1800+
y: [1, 3, 2, 4],
1801+
legendgroup: 'foo'
1802+
}], {
1803+
legend: {
1804+
groupclick: 'toggleitem'
1805+
}
1806+
}).then(done);
1807+
});
1808+
1809+
it('toggles visibilities', function(done) {
1810+
Promise.resolve()
1811+
.then(assertVisible([false, true, true, true]))
1812+
.then(click(0))
1813+
.then(assertVisible([false, 'legendonly', true, true]))
1814+
.then(click(0))
1815+
.then(assertVisible([false, true, true, true]))
1816+
.then(click(1))
1817+
.then(assertVisible([false, true, true, 'legendonly']))
1818+
.then(click(1))
1819+
.then(assertVisible([false, true, true, true]))
1820+
.then(click(2))
1821+
.then(assertVisible([false, true, 'legendonly', true]))
1822+
.then(click(2))
1823+
.then(assertVisible([false, true, true, true]))
1824+
.then(done, done.fail);
1825+
});
1826+
});
1827+
17851828
describe('legend visibility toggles with groupby', function() {
17861829
beforeEach(function(done) {
17871830
Plotly.newPlot(gd, [{

test/plot-schema.json

+12-2
Original file line numberDiff line numberDiff line change
@@ -2683,8 +2683,18 @@
26832683
"valType": "number"
26842684
}
26852685
},
2686+
"groupclick": {
2687+
"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.",
2688+
"dflt": "togglegroup",
2689+
"editType": "legend",
2690+
"valType": "enumerated",
2691+
"values": [
2692+
"toggleitem",
2693+
"togglegroup"
2694+
]
2695+
},
26862696
"itemclick": {
2687-
"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.",
2697+
"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.",
26882698
"dflt": "toggle",
26892699
"editType": "legend",
26902700
"valType": "enumerated",
@@ -2695,7 +2705,7 @@
26952705
]
26962706
},
26972707
"itemdoubleclick": {
2698-
"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.",
2708+
"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.",
26992709
"dflt": "toggleothers",
27002710
"editType": "legend",
27012711
"valType": "enumerated",

0 commit comments

Comments
 (0)