Skip to content

Commit

Permalink
improve and 🔒 plotly_legend(double)click event data
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
etpinard committed Apr 30, 2018
1 parent 47b1f44 commit 02a85bf
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 7 deletions.
18 changes: 11 additions & 7 deletions src/components/legend/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -355,14 +355,14 @@ module.exports = function draw(gd) {
}
};

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

var evtData = {
event: evt,
node: clickedTrace.node(),
itemNumber: datum.i,
curveNumber: datum.trace.index,
node: legendItem.node(),
curveNumber: trace.index,
expandedIndex: trace._expandedIndex,
data: gd.data,
layout: gd.layout,
frames: gd._transitionData._frames,
Expand All @@ -371,20 +371,24 @@ function clickOrDoubleClick(gd, legend, clickedTrace, numClicks, evt) {
fullLayout: gd._fullLayout
};

if(trace._group) {
evtData.group = trace._group;
}

var returnVal;

if(numClicks === 1) {
legend._clickTimeout = setTimeout(function() {
returnVal = Events.triggerHandler(gd, 'plotly_legendclick', evtData);
if(returnVal !== false) handleClick(clickedTrace, gd, numClicks);
if(returnVal !== false) handleClick(legendItem, gd, numClicks);
}, DBLCLICKDELAY);
}
else if(numClicks === 2) {
if(legend._clickTimeout) clearTimeout(legend._clickTimeout);
gd._legendMouseDownTime = 0;

returnVal = Events.triggerHandler(gd, 'plotly_legenddoubleclick', evtData);
if(returnVal !== false) handleClick(clickedTrace, gd, numClicks);
if(returnVal !== false) handleClick(legendItem, gd, numClicks);
}
}

Expand Down
108 changes: 108 additions & 0 deletions test/jasmine/tests/legend_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1299,5 +1299,113 @@ describe('legend interaction', function() {
.catch(failTest);
});
});

describe('legend click/doubleclick event data', function() {
function _assert(act, exp) {
for(var k in exp) {
if(k === 'event' || k === 'node') {
expect(act[k]).toBeDefined();
} else if(k === 'group') {
expect(act[k]).toEqual(exp[k]);
} else {
expect(act[k]).toBe(exp[k], 'key ' + k);

This comment has been minimized.

Copy link
@alexcjohnson

alexcjohnson Apr 30, 2018

Collaborator

not sure it's worth changing until someone breaks this test, but _fullData and _fullLayout, if they ever fail, can flood the test output with their super-long string representations #2227 (comment)

}
}

expect(Object.keys(act).length)
.toBe(Object.keys(exp).length, '# of keys');
}

function clickAndCheck(clickArg, exp) {
Lib.extendFlat(exp, {
event: true,
node: true,
data: gd.data,
layout: gd.layout,
frames: gd._transitionData._frames,
config: gd._context,
fullData: gd._fullData,
fullLayout: gd._fullLayout
});

var evtName = {
1: 'plotly_legendclick',
2: 'plotly_legenddoubleclick'
}[clickArg[1]];

return new Promise(function(resolve, reject) {
var hasBeenCalled = false;

var to = setTimeout(function() {
reject('did not trigger ' + evtName);
}, 2 * DBLCLICKDELAY);

gd.on(evtName, function(d) {
hasBeenCalled = true;
_assert(d, exp);
});
gd.on('plotly_restyle', function() {
if(hasBeenCalled) {
clearTimeout(to);
resolve();
}
});

click(clickArg[0], clickArg[1])();
});
}

it('should have correct keys (base case)', function(done) {
Plotly.newPlot(gd, [{
x: [1, 2, 3, 4, 5],
y: [1, 2, 1, 2, 3]
}], {
showlegend: true
})
.then(function() {
return clickAndCheck([0, 1], {
curveNumber: 0,
expandedIndex: 0
});
})
.then(function() {
return clickAndCheck([0, 2], {
curveNumber: 0,
expandedIndex: 0
});
})
.catch(failTest)
.then(done);
});

it('should have correct keys (groupby case)', function(done) {
Plotly.newPlot(gd, [{
x: [1, 2, 3, 4, 5],
y: [1, 2, 1, 2, 3],
transforms: [{
type: 'groupby',
groups: ['a', 'b', 'b', 'a', 'b']
}]
}, {
x: [1, 2, 3, 4, 5],
y: [1, 2, 1, 2, 3],
}])
.then(function() {
return clickAndCheck([1, 1], {
curveNumber: 0,
expandedIndex: 1,
group: 'b'
});
})
.then(function() {
return clickAndCheck([2, 2], {
curveNumber: 1,
expandedIndex: 2
});
})
.catch(failTest)
.then(done);
});
});

This comment has been minimized.

Copy link
@alexcjohnson

alexcjohnson Apr 30, 2018

Collaborator

Great tests! Can you include one with pies, showing how the event indicates the label you clicked on?

});
});

0 comments on commit 02a85bf

Please sign in to comment.