-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hover / unhover events on the 2d WebGL plots #994
Changes from all commits
53c7c11
c4baeb2
359d50a
1e56d7f
2e8db74
9f77c11
2e54a99
57cec8c
a9b8b3e
c1abd3e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,7 @@ function Scene2D(options, fullLayout) { | |
this.staticPlot = !!options.staticPlot; | ||
|
||
this.fullLayout = fullLayout; | ||
this.fullData = null; | ||
this.updateAxes(fullLayout); | ||
|
||
this.makeFramework(); | ||
|
@@ -49,6 +50,7 @@ function Scene2D(options, fullLayout) { | |
|
||
// trace set | ||
this.traces = {}; | ||
this._inputs = {}; | ||
|
||
// create axes spikes | ||
this.spikes = createSpikes(this.glplot); | ||
|
@@ -58,6 +60,9 @@ function Scene2D(options, fullLayout) { | |
outerFill: true | ||
}); | ||
|
||
// last button state | ||
this.lastButtonState = 0; | ||
|
||
// last pick result | ||
this.pickResult = null; | ||
|
||
|
@@ -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; | ||
}; | ||
|
@@ -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++) { | ||
|
@@ -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]; | ||
|
||
|
@@ -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, { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. very nicely done. |
||
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; | ||
|
||
|
@@ -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; | ||
|
@@ -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 || | ||
|
@@ -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('+'); | ||
|
@@ -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); | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -128,6 +128,7 @@ proto.handlePick = function(pickResult) { | |
this.color[index] : | ||
this.color, | ||
name: this.name, | ||
pointIndex: index, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great. Now, can you add |
||
hoverinfo: this.hoverinfo | ||
}; | ||
}; | ||
|
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); | ||
}; |
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); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@etpinard I added
this.fullData
andthis._inputs
to retain info prerequisite for the event data contents you suggested (below), please let me know if there's a better way. Working oncurveNumber
andpointNumber
now, I suppose these are just the indices.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very nice.