UNPKG

dash-renderer

Version:

render dash components in react

167 lines (136 loc) 6.87 kB
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); }); }; var IPYTHON_VERSION = '3'; require(["widgets/js/widget", "widgets/js/manager"], function (widget, manager) { if (!('DOMWidgetView' in widget)) { // we're in IPython2, things moved a bit from 2 --> 3. // construct the expected IPython3 widget API IPYTHON_VERSION = '2'; manager = {WidgetManager: widget}; widget = {DOMWidgetView: IPython.DOMWidgetView}; } var GraphView = widget.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); // for some reason the 'width' is being changed in IPython 3.0.0 // for the containing `div` element. There's a flicker here, but // I was unable to fix it otherwise. setTimeout(function () { if (IPYTHON_VERSION === '3') { $('#' + graphId)[0].parentElement.style.width = '100%'; } }, 500); // 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; delete message.points[i].fullData; } } that.send({event: message.type, message: message, graphId: graphId}); } else if (message.task === 'getAttributes') { that.send({event: 'getAttributes', response: message.response}); } } } }; 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; if (message.fadeTo) { this.fadeTo(message); } else { var plot = $('#' + message.graphId)[0].contentWindow; plot.postMessage(message, window.plotlyDomains[message.graphId]); } } return GraphView.__super__.update.apply(this); }, /** * Wrapper for jquery's `fadeTo` function. * * @param message Contains the id we need to find the element. */ fadeTo: function (message) { var plot = $('#' + message.graphId); plot.fadeTo(message.duration, message.opacity); } }); // Register the GraphView with the widget manager. manager.WidgetManager.register_widget_view('GraphView', GraphView); }); //@ sourceURL=graphWidget.js