Skip to content

Commit 02a85bf

Browse files
committed
improve and 🔒 plotly_legend(double)click event data
- add 'expandIndex' for all traces - add 'group' for traces with enable groupby transforms - 🔪 itemNumber (which was undefined on double click, can add it back in future if someone asks for it.
1 parent 47b1f44 commit 02a85bf

File tree

2 files changed

+119
-7
lines changed

2 files changed

+119
-7
lines changed

Diff for: src/components/legend/draw.js

+11-7
Original file line numberDiff line numberDiff line change
@@ -355,14 +355,14 @@ module.exports = function draw(gd) {
355355
}
356356
};
357357

358-
function clickOrDoubleClick(gd, legend, clickedTrace, numClicks, evt) {
359-
var datum = clickedTrace.data()[0][0];
358+
function clickOrDoubleClick(gd, legend, legendItem, numClicks, evt) {
359+
var trace = legendItem.data()[0][0].trace;
360360

361361
var evtData = {
362362
event: evt,
363-
node: clickedTrace.node(),
364-
itemNumber: datum.i,
365-
curveNumber: datum.trace.index,
363+
node: legendItem.node(),
364+
curveNumber: trace.index,
365+
expandedIndex: trace._expandedIndex,
366366
data: gd.data,
367367
layout: gd.layout,
368368
frames: gd._transitionData._frames,
@@ -371,20 +371,24 @@ function clickOrDoubleClick(gd, legend, clickedTrace, numClicks, evt) {
371371
fullLayout: gd._fullLayout
372372
};
373373

374+
if(trace._group) {
375+
evtData.group = trace._group;
376+
}
377+
374378
var returnVal;
375379

376380
if(numClicks === 1) {
377381
legend._clickTimeout = setTimeout(function() {
378382
returnVal = Events.triggerHandler(gd, 'plotly_legendclick', evtData);
379-
if(returnVal !== false) handleClick(clickedTrace, gd, numClicks);
383+
if(returnVal !== false) handleClick(legendItem, gd, numClicks);
380384
}, DBLCLICKDELAY);
381385
}
382386
else if(numClicks === 2) {
383387
if(legend._clickTimeout) clearTimeout(legend._clickTimeout);
384388
gd._legendMouseDownTime = 0;
385389

386390
returnVal = Events.triggerHandler(gd, 'plotly_legenddoubleclick', evtData);
387-
if(returnVal !== false) handleClick(clickedTrace, gd, numClicks);
391+
if(returnVal !== false) handleClick(legendItem, gd, numClicks);
388392
}
389393
}
390394

Diff for: test/jasmine/tests/legend_test.js

+108
Original file line numberDiff line numberDiff line change
@@ -1299,5 +1299,113 @@ describe('legend interaction', function() {
12991299
.catch(failTest);
13001300
});
13011301
});
1302+
1303+
describe('legend click/doubleclick event data', function() {
1304+
function _assert(act, exp) {
1305+
for(var k in exp) {
1306+
if(k === 'event' || k === 'node') {
1307+
expect(act[k]).toBeDefined();
1308+
} else if(k === 'group') {
1309+
expect(act[k]).toEqual(exp[k]);
1310+
} else {
1311+
expect(act[k]).toBe(exp[k], 'key ' + k);
1312+
}
1313+
}
1314+
1315+
expect(Object.keys(act).length)
1316+
.toBe(Object.keys(exp).length, '# of keys');
1317+
}
1318+
1319+
function clickAndCheck(clickArg, exp) {
1320+
Lib.extendFlat(exp, {
1321+
event: true,
1322+
node: true,
1323+
data: gd.data,
1324+
layout: gd.layout,
1325+
frames: gd._transitionData._frames,
1326+
config: gd._context,
1327+
fullData: gd._fullData,
1328+
fullLayout: gd._fullLayout
1329+
});
1330+
1331+
var evtName = {
1332+
1: 'plotly_legendclick',
1333+
2: 'plotly_legenddoubleclick'
1334+
}[clickArg[1]];
1335+
1336+
return new Promise(function(resolve, reject) {
1337+
var hasBeenCalled = false;
1338+
1339+
var to = setTimeout(function() {
1340+
reject('did not trigger ' + evtName);
1341+
}, 2 * DBLCLICKDELAY);
1342+
1343+
gd.on(evtName, function(d) {
1344+
hasBeenCalled = true;
1345+
_assert(d, exp);
1346+
});
1347+
gd.on('plotly_restyle', function() {
1348+
if(hasBeenCalled) {
1349+
clearTimeout(to);
1350+
resolve();
1351+
}
1352+
});
1353+
1354+
click(clickArg[0], clickArg[1])();
1355+
});
1356+
}
1357+
1358+
it('should have correct keys (base case)', function(done) {
1359+
Plotly.newPlot(gd, [{
1360+
x: [1, 2, 3, 4, 5],
1361+
y: [1, 2, 1, 2, 3]
1362+
}], {
1363+
showlegend: true
1364+
})
1365+
.then(function() {
1366+
return clickAndCheck([0, 1], {
1367+
curveNumber: 0,
1368+
expandedIndex: 0
1369+
});
1370+
})
1371+
.then(function() {
1372+
return clickAndCheck([0, 2], {
1373+
curveNumber: 0,
1374+
expandedIndex: 0
1375+
});
1376+
})
1377+
.catch(failTest)
1378+
.then(done);
1379+
});
1380+
1381+
it('should have correct keys (groupby case)', function(done) {
1382+
Plotly.newPlot(gd, [{
1383+
x: [1, 2, 3, 4, 5],
1384+
y: [1, 2, 1, 2, 3],
1385+
transforms: [{
1386+
type: 'groupby',
1387+
groups: ['a', 'b', 'b', 'a', 'b']
1388+
}]
1389+
}, {
1390+
x: [1, 2, 3, 4, 5],
1391+
y: [1, 2, 1, 2, 3],
1392+
}])
1393+
.then(function() {
1394+
return clickAndCheck([1, 1], {
1395+
curveNumber: 0,
1396+
expandedIndex: 1,
1397+
group: 'b'
1398+
});
1399+
})
1400+
.then(function() {
1401+
return clickAndCheck([2, 2], {
1402+
curveNumber: 1,
1403+
expandedIndex: 2
1404+
});
1405+
})
1406+
.catch(failTest)
1407+
.then(done);
1408+
});
1409+
});
13021410
});
13031411
});

0 commit comments

Comments
 (0)