Skip to content

Commit

Permalink
Merge pull request #994 from monfera/FI-71
Browse files Browse the repository at this point in the history
Hover / unhover events on the 2d WebGL plots
  • Loading branch information
etpinard authored Oct 5, 2016
2 parents fce36fa + c1abd3e commit 293f201
Show file tree
Hide file tree
Showing 8 changed files with 571 additions and 13 deletions.
44 changes: 42 additions & 2 deletions src/plots/gl2d/scene2d.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ function Scene2D(options, fullLayout) {
this.staticPlot = !!options.staticPlot;

this.fullLayout = fullLayout;
this.fullData = null;
this.updateAxes(fullLayout);

this.makeFramework();
Expand All @@ -49,6 +50,7 @@ function Scene2D(options, fullLayout) {

// trace set
this.traces = {};
this._inputs = {};

// create axes spikes
this.spikes = createSpikes(this.glplot);
Expand All @@ -58,6 +60,9 @@ function Scene2D(options, fullLayout) {
outerFill: true
});

// last button state
this.lastButtonState = 0;

// last pick result
this.pickResult = null;

Expand Down Expand Up @@ -332,6 +337,8 @@ proto.destroy = function() {
this.container.removeChild(this.svgContainer);
this.container.removeChild(this.mouseContainer);

this.fullData = null;
this._inputs = null;
this.glplot = null;
this.stopped = true;
};
Expand Down Expand Up @@ -422,6 +429,8 @@ proto.updateTraces = function(fullData, calcData) {
var traceIds = Object.keys(this.traces);
var i, j, fullTrace;

this.fullData = fullData;

// remove empty traces
trace_id_loop:
for(i = 0; i < traceIds.length; i++) {
Expand All @@ -443,7 +452,7 @@ proto.updateTraces = function(fullData, calcData) {
// update / create trace objects
for(i = 0; i < fullData.length; i++) {
fullTrace = fullData[i];

this._inputs[fullTrace.uid] = i;
var calcTrace = calcData[i],
traceObj = this.traces[fullTrace.uid];

Expand All @@ -455,6 +464,24 @@ proto.updateTraces = function(fullData, calcData) {
}
};

proto.emitPointAction = function(nextSelection, eventType) {

var curveIndex = this._inputs[nextSelection.trace.uid];

this.graphDiv.emit(eventType, {
points: [{
x: nextSelection.traceCoord[0],
y: nextSelection.traceCoord[1],
curveNumber: curveIndex,
pointNumber: nextSelection.pointIndex,
data: this.fullData[curveIndex]._input,
fullData: this.fullData,
xaxis: this.xaxis,
yaxis: this.yaxis
}]
});
};

proto.draw = function() {
if(this.stopped) return;

Expand All @@ -463,8 +490,11 @@ proto.draw = function() {
var glplot = this.glplot,
camera = this.camera,
mouseListener = camera.mouseListener,
mouseUp = this.lastButtonState === 1 && mouseListener.buttons === 0,
fullLayout = this.fullLayout;

this.lastButtonState = mouseListener.buttons;

this.cameraChanged();

var x = mouseListener.x * glplot.pixelRatio;
Expand Down Expand Up @@ -494,8 +524,13 @@ proto.draw = function() {
(y / glplot.pixelRatio) - (size.t + (1 - domainY[1]) * size.h)
);

var nextSelection = result && result.object._trace.handlePick(result);

if(nextSelection && mouseUp) {
this.emitPointAction(nextSelection, 'plotly_click');
}

if(result && result.object._trace.hoverinfo !== 'skip' && fullLayout.hovermode) {
var nextSelection = result.object._trace.handlePick(result);

if(nextSelection && (
!this.lastPickResult ||
Expand All @@ -522,6 +557,10 @@ proto.draw = function() {
glplot.pixelRatio
];

// this needs to happen before the next block that deletes traceCoord data
// also it's important to copy, otherwise data is lost by the time event data is read
this.emitPointAction(nextSelection, 'plotly_hover');

var hoverinfo = selection.hoverinfo;
if(hoverinfo !== 'all') {
var parts = hoverinfo.split('+');
Expand Down Expand Up @@ -549,6 +588,7 @@ proto.draw = function() {
else if(!result && this.lastPickResult) {
this.spikes.update({});
this.lastPickResult = null;
this.graphDiv.emit('plotly_unhover');
Fx.loneUnhover(this.svgContainer);
}
}
Expand Down
16 changes: 10 additions & 6 deletions src/traces/contourgl/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,24 @@ function Contour(scene, uid) {
var proto = Contour.prototype;

proto.handlePick = function(pickResult) {
var index = pickResult.pointId,
options = this.heatmapOptions,
shape = options.shape;
var options = this.heatmapOptions,
shape = options.shape,
index = pickResult.pointId,
xIndex = index % shape[0],
yIndex = Math.floor(index / shape[0]),
zIndex = index;

return {
trace: this,
dataCoord: pickResult.dataCoord,
traceCoord: [
options.x[index % shape[0]],
options.y[Math.floor(index / shape[0])],
options.z[index]
options.x[xIndex],
options.y[yIndex],
options.z[zIndex]
],
textLabel: this.textLabels[index],
name: this.name,
pointIndex: [xIndex, yIndex],
hoverinfo: this.hoverinfo
};
};
Expand Down
15 changes: 10 additions & 5 deletions src/traces/heatmapgl/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,24 @@ function Heatmap(scene, uid) {
var proto = Heatmap.prototype;

proto.handlePick = function(pickResult) {
var index = pickResult.pointId,
shape = this.options.shape;
var options = this.options,
shape = options.shape,
index = pickResult.pointId,
xIndex = index % shape[0],
yIndex = Math.floor(index / shape[0]),
zIndex = index;

return {
trace: this,
dataCoord: pickResult.dataCoord,
traceCoord: [
this.options.x[index % shape[0]],
this.options.y[Math.floor(index / shape[0])],
this.options.z[index]
options.x[xIndex],
options.y[yIndex],
options.z[zIndex]
],
textLabel: this.textLabels[index],
name: this.name,
pointIndex: [xIndex, yIndex],
hoverinfo: this.hoverinfo
};
};
Expand Down
1 change: 1 addition & 0 deletions src/traces/pointcloud/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ proto.handlePick = function(pickResult) {
this.textLabels,
color: this.color,
name: this.name,
pointIndex: index,
hoverinfo: this.hoverinfo
};
};
Expand Down
1 change: 1 addition & 0 deletions src/traces/scattergl/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ proto.handlePick = function(pickResult) {
this.color[index] :
this.color,
name: this.name,
pointIndex: index,
hoverinfo: this.hoverinfo
};
};
Expand Down
5 changes: 5 additions & 0 deletions test/jasmine/assets/hover.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
var mouseEvent = require('./mouse_event');

module.exports = function hover(x, y) {
mouseEvent('mousemove', x, y);
};
17 changes: 17 additions & 0 deletions test/jasmine/assets/timed_click.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
var mouseEvent = require('./mouse_event');

module.exports = function click(x, y) {
mouseEvent('mousemove', x, y, {buttons: 0});

window.setTimeout(function() {

mouseEvent('mousedown', x, y, {buttons: 1});

window.setTimeout(function() {

mouseEvent('mouseup', x, y, {buttons: 0});

}, 50);

}, 150);
};
Loading

0 comments on commit 293f201

Please sign in to comment.