forked from plotly/plotly.py
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgraphWidget.js
More file actions
129 lines (104 loc) · 5.3 KB
/
graphWidget.js
File metadata and controls
129 lines (104 loc) · 5.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
window.genUID = function() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
};
require(["widgets/js/widget"], function(WidgetManager){
var GraphView = IPython.DOMWidgetView.extend({
render: function(){
var that = this;
var graphId = window.genUID();
var loadingId = 'loading-'+graphId;
var _graph_url = that.model.get('_graph_url');
// variable plotlyDomain in the case of enterprise
var url_parts = _graph_url.split('/');
var plotlyDomain = url_parts[0] + '//' + url_parts[2];
if(!('plotlyDomains' in window)){
window.plotlyDomains = {};
}
window.plotlyDomains[graphId] = plotlyDomain;
// Place IFrame in output cell div `$el`
that.$el.css('width', '100%');
that.$graph = $(['<iframe id="'+graphId+'"',
'src="'+_graph_url+'.embed"',
'seamless',
'style="border: none;"',
'width="100%"',
'height="600">',
'</iframe>'].join(' '));
that.$graph.appendTo(that.$el);
that.$loading = $('<div id="'+loadingId+'">Initializing...</div>')
.appendTo(that.$el);
// initialize communication with the iframe
if(!('pingers' in window)){
window.pingers = {};
}
window.pingers[graphId] = setInterval(function() {
that.graphContentWindow = $('#'+graphId)[0].contentWindow;
that.graphContentWindow.postMessage({task: 'ping'}, plotlyDomain);
}, 200);
// Assign a message listener to the 'message' events
// from iframe's postMessage protocol.
// Filter the messages by iframe src so that the right message
// gets passed to the right widget
if(!('messageListeners' in window)){
window.messageListeners = {};
}
window.messageListeners[graphId] = function(e) {
if(_graph_url.indexOf(e.origin)>-1) {
var frame = document.getElementById(graphId);
if(frame === null){
// frame doesn't exist in the dom anymore, clean up it's old event listener
window.removeEventListener('message', window.messageListeners[graphId]);
clearInterval(window.pingers[graphId]);
} else if(frame.contentWindow === e.source) {
// TODO: Stop event propagation, so each frame doesn't listen and filter
var frameContentWindow = $('#'+graphId)[0].contentWindow;
var message = e.data;
if('pong' in message && message.pong) {
$('#loading-'+graphId).hide();
clearInterval(window.pingers[graphId]);
that.send({event: 'pong', graphId: graphId});
} else if (message.type==='hover' ||
message.type==='zoom' ||
message.type==='click' ||
message.type==='unhover') {
// click and hover events contain all of the data in the traces,
// which can be a very large object and may take a ton of time
// to pass to the python backend. Strip out the data, and require
// the user to call get_figure if they need trace information
if(message.type !== 'zoom') {
for(var i in message.points) {
delete message.points[i].data;
}
}
that.send({event: message.type, message: message, graphId: graphId});
}
}
}
};
window.removeEventListener('message', window.messageListeners[graphId]);
window.addEventListener('message', window.messageListeners[graphId]);
},
update: function() {
// Listen for messages from the graph widget in python
var jmessage = this.model.get('_message');
var message = JSON.parse(jmessage);
// check for duplicate messages
if(!('messageIds' in window)){
window.messageIds = {};
}
if(!(message.uid in window.messageIds)){
// message hasn't been received yet, do stuff
window.messageIds[message.uid] = true;
var plot = $('#'+message.graphId)[0].contentWindow;
plot.postMessage(message, window.plotlyDomains[message.graphId]);
}
return GraphView.__super__.update.apply(this);
}
});
// Register the GraphView with the widget manager.
WidgetManager.register_widget_view('GraphView', GraphView);
});
//@ sourceURL=graphWidget.js