15125 lines
1.4 MiB
15125 lines
1.4 MiB
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import replot\n",
|
|
"import numpy as np"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"%matplotlib notebook\n",
|
|
"%load_ext autoreload\n",
|
|
"%autoreload 2"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"with replot.Figure() as figure:\n",
|
|
" for i in range(8):\n",
|
|
" figure.plot(lambda x: np.sin(x + np.pi * i / 4))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.sin, (-2, 2))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"scrolled": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"with replot.Figure() as figure:\n",
|
|
" x = np.linspace(-np.pi, np.pi, 200)\n",
|
|
" figure.plot(np.sin, x)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"with replot.Figure() as figure:\n",
|
|
" x = range(10)\n",
|
|
" figure.plot(x)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"scrolled": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"with replot.Figure() as figure:\n",
|
|
" x = range(10)\n",
|
|
" figure.plot(x, x)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"with replot.Figure() as figure:\n",
|
|
" x = range(10)\n",
|
|
" figure.plot(x, x, label=\"x\")\n",
|
|
" figure.xlabel = \"some x label\"\n",
|
|
" figure.ylabel = \"some y label\"\n",
|
|
" figure.title = \"A title for the figure\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"with replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=\"best\") as figure:\n",
|
|
" figure.plot(np.sin, label=\"sin\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"with replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=True) as figure:\n",
|
|
" figure.plot(np.sin, label=\"sin\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"fig = replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=\"best\")\n",
|
|
"fig.plot(np.sin, label=\"sin\")\n",
|
|
"fig.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"with replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\") as figure:\n",
|
|
" figure.plot(np.sin, label=\"sin\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"scrolled": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAG4CAYAAADVDFZ+AAAgAElEQVR4nOy9B5RcR3YlyO6WW400knab0xLV3QTBqtppaaSd0VlJu2dHZmaPNDvnSLszp0V2kyBBwnvvvSe8I1DwHgThvfcehPe+stJbECSb7FEbNZu18SL+/5koZFZl5jcvzLvn3FNVWVn53/+vIuJFxIv7XniBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFA8Bh1dXU/rq2t/etW3hOpqanp6OY67BpzGXPss75gn/XHbj6rNbDP/xt2ra/Yt1/38nPZZ/4ds/8h+/o5+zqVfX2TfX3g5TUIBAKBQCAQWgQLQDpAoMMCnvdaey8LVN5h70209J5SgZPbAJD97f/BPvdnbdq0+f1qP6MU2OeuZvata3Y9uI9fvuBxAAjBH/vsgV5+JoFAIBAIBEJFYAHJZRboPGHMsh9/taX3sve8yxhv6T0suPlbK3D6RrPruA0A32rt2mWg6P0FHAD+4tVXX/3PXn5mGWjRrwQCgUAgEAxC27Zt/3cIcliw8/ewugbbkS289z+y3/+U8UvY8oVtWPb9G/A7WPGDoIbxO+z7n8Bn2u9hnz0c3tM8AGzTps2/Ze/bC4EnrCqy39e/9NJLv1ns2ux34wuvzb7esWz6HfaZy+DvrSB2P3utzv479rtx7P1n2esT2dcU+3q3yGePYPwXxp8X2PxtOwBk/D577RFs2TIeefnll/+g4PN/HVZO2esh9p5P2NdTjP++xPOrtWyHz/wJXIc9r/+r+arqiy+++Fvs5zXs9acQ8DL2tZ5Pe+uaz62wNv8MK6DdzL4usp8LvP6d73znJfb9Bsak9dw3sGf+zVI+JxAIBAKBoCEgUGC8Zn2/kQUN51p6vxVoPLcKZweA8H3BytnXmv2tEwD+4R/+4f9iBSZ92Y+/8u1vf/t/huCKcWkl14YAkr1+nH3uiyyg/A0rRzBuB5JWAPgv7LVR7Mdfg/eUeg4lVgC/Yq+vh6Dsm9/85m/D84H3FvzdmoKg8Ovsb3pCjiIEpqXuw3pW/6nUfbHvVzFefOWVV74F9rLfL7eC08IA8JmVySKfsdr6m3fYj9+w7vvXINeQ/W46/AzPiH3WWrC/lK0EAoFAIBA0AwsCfpcN/v/MgoKu8DMEJRBYsODlT0r9TYUBYMkcQPZ1QPNgE1bDYBXyhWaBY6lrQy6gdd1/V/C2X2Hv+5h9/uvWdca1lrNo2V9yC5i9/ocFr0GAdw++t4JYuH5Ns8963NJKauGzKnJfX4NnwK7zX+zfQ+BprXxWGgCeL7wu+/m/N38WcG9gD6wMtvR8CAQCgUAgaAI4iABbkrC6Zb30NSt4WVzqb7wKAGFr0lqh+tQme+1HEJAWbrG2dG0WqP45XKf5tjF731X2+mDLlnGtrWpa9pSVA1hoA/v+L6wVwsJ7+Ix9/R/s69AWrlUyAGSv/xv4PeP3mt3Tx5UGgIwfNLvuUMg/bG4vPHM4YNPaMyIQCAQCgaABIK/NCsLSjBmgtSL4RUFQ+AxYoPB2awEg+/u/KmMFcCz7+ViF9hZbAWy+YvkN2Fpmn/+adR1YATzT2mez96ysNABk1/1urcif/HYl91HOCiD7/f9TYMe/brYC+GdwXVgZLPiMkUVWAJ+5H/h79npDJbYSCAQCgUDQCNahDziM8New6lTAGlgVZL/vVezv2Pv/Dg4wQM5es9edoAYOO1iB0R8VvqcwAITDInBoArZU2Wf9T/Zr7Of/r5TNpXIAIYcNbIfPYe+ZDduc3/rWt/6VdZ9lBYDsfVOsLdOvF7xWzkrbdsbdEAzCzxCUQfAG+XulrtVKAGjnAF6AABdWN9n3SwpzAK1DIj+yVjkhYPz38GxbCwDh79hrUfa7iRBUwmvw3OztcgKBQCAQCJqDBQE7GA+V+B0cpHjutKwFWGGDwyJPrW3EH1p/88vCoKY2L9j8qb0dyr4PF54ChtO6YAesQFpbkXetwxpFUSwAhDxG6xRw0tomPcCCr//V/n25ASD7m5chALS3RgtPAb/QQgBonQIeW3BKGE7XbmtJq7D5s2r+mQWngOFUMZxu7sOYLQzUIFCG1TzrJPZ+OGndWgAIgO31WnFwJWYFkY/Z3y5o7fkQCAQCgUAgEAKEdVgHVmv/EtsWAoFAkAasU5xvbX98xWbxf1rqfWyW28lKcG+oFVIT3yj1XgKBQMCCpaUIZfW+bp00hhVXKBXnqSA1gUAgKA0QpwUJA9heKhUAshl0GxCBBa0w+Blydtj3PYK1lEAgEFoH65teZf3VrVpRKxjEoEHcuhbbLgKBQJASsApYKgCEZGmQnbB/ZjPs/1pOXhCBQCAQCAQCQWK0EgC+z2bVwwp+/h6chgvMOAKBQCAQCASC96gkAAR5CgoACeXg/ts/+HeP2/9gQ8M7r2ca2v/g08ftXz/68J3X/t8XSlSrIBDc4OHbr/3nx++8vo/9nz1lX5+w/73tj9q/9hfYdhG0xNca3vpBO/a/dpb1b581vPOD+KN3frDi/pvfp3QDglrwawv4q6++aiKYic+OHmxq6PBGE+sYn2N2yYKmX/7859gmEjTBV19+2fTkg9VF/9eAn+za1kR9EcEr/PInP2lKzZ5W9H8t1KV90xcXzmKb6Am8ii8IkqOlAPDll19+BfS5QPT0BSGcCodAepbzufBP9PTpF00ff0zUneBn29+JbdtEh/juD5via9c05RoTTU+SHzclDxxsCvXoyH8XmfFe05PsZ+h2E937G9OOJ08+b4otfF/8v7HBN7lzV9OTeLYpF003JTZvbmro2I7/Lr5mNfozU5my+BubT9JPm8LjRopgr2+3ptSxE+y1T5pyjyNNsaWLnX4vdegwuq1u/e1pkEGQD6CSD2KpLAD8F6uU1WN4nX2/nH3/D/b7LBmYEMjAgHDsC2XKwECHwRvNE6LuBD8D0mfO8w4QVv9SJ04/977M/VBTqE833lHGVq1Ct5vozt/Y7Tux1ZpsdO/QlLlx97nfpz+60tTQ6S3+nuSBQ+jPTVXK4m9sRt+fx/+XGof0a8o2xJ/7fXLvfvH/yCYe6Wu30O1142+fwg6CKaAOwxyCn7/8/POmUK/OvANM7Npd8r2Zm/fYoCxWZtIXLqHbTqzO39jtO3Pnofg/YhOO9IXLJd+XOnZSDMpd2zdlHzaiPzsVKYO/sZk6fkqs/LHJRvZB6f+j+Pr1Ikgc2Lspl3qKbne1/saOHwiKw/QOwySCn3Orl4vt3envNeVyn7f4/sSOndZMun9TLvMpuv3Eyv2N2b5z2R81hUcPt1aSV7b6/mj9QvG/OXM6+rNTkdj+xmYunuNbvnwl+dCRlt8L/5tjxTYxpMBg216tv7HjB4LiMLnDMI3Z2/fF1m+nt5qyj6Otvh86ycbhg8RqIQsGse0nVkbsgCB55LiYQAzq05RLfdLq+7PRDF+54avOH11Bf36qEdvf2IytXiUmEJMntDq5BWZuPxCH4Dq1K6s/lI0UABJcw+QOwzRGpk4SM97168r+G56fBVsqPTqyGfYT9Hsglk/MgABWjCHwg/+d1NETZf+dveocHjW0rEGcKIe/sZkNJ5saOr/NJ7iZu4/L/rvoIrHqHFtcj34P1fgbO34gKA5TOwzTCMn3fDWmV+emJ8nKArnI1MliFXDrNvT7IJZPzIAguf9gPpDL/qjsv+OB44DeInA8dxH9GapEkwNAOKwG/zPR+XMr+jtY+eOn0Du82WLOoIykAJDgGqZ2GKYxOm+20FvbubVif6cvXnUkFXJpygVUhVgBAazcNQ4bKIK4U2cr/ns4nCS28sajP0OVaGoAmItm8qt/98pf/bMZW7ZUrAKuWI5+L5X6Gzt+ICgOEzsM05h9FBG5LqyT/PKLzyv2NwzodsI0yXSoQ6yAAE6NO7l/Faz+2cwlP24K9ezEP6OYbAxRLn9jM7F9h5gwzJ5R1d+D7BXPje72rlJpLhQAElzDxA7DNMbXrRUz3CWLqh4gbJkOCASx74dYHrECAjhh7vbgUPyDD8T/7CL1crNM8zcm+UE1K9fUzcGhyLQp4n92Z2lpLNlIASDBNUzrMEwjdJC2NELm5t2qBwjIzbL1A0HbDfu+iK0TIyDINsTEakrX9lyWo+rPgdws/jnv8BVB7GepAk0MACFPlK82D+3v6tBQ/nMGKHP4iAJAgmuY1mGYxtTp804yvtsBwpZZiK1cgX5fxNaJERDw0m6QjL/wfdefZZ9ahwMl2M9SBZoYAEbnzPJEpopPlPv3FBPc63fQ76tcf2PHDwTFYVqHYRojs6ZbVT/2uB4gIMGaHwbp2YmEoRVg0AEBP/wxpL/Yjrt41fXnOWkH40ehP0sVaFoACPl6/PAHnOCNpFx/XnzdOjHBXb4M/d7K9Td2/EBQHCZ1GKYRtuC4xAFjLpb1ZIAIjxkhTneeuYB+f8SWGXRAAHVV+QRhQK+qDn80J5w4B/1J+EwVhXp19zc24UAaP/wxbYonn5e512BNcDsrMcGlAJDgGiZ1GKYxefCIU/bN7jDc+ts+cRddMB/9/ogtM+iAILZypSU0vt6zz7TLw5EGpXz+xiZU/OApAkeOefaZttoBpM5g3185/saOHwiKw6QOwzTapzHtupheDBBOkj9IJqRbL+9FxGOQAQFs/8LKnzhsdN+zz7WT88NjhqM/T9lpUgCYDafyh408PCTkTHDrF6DfYzn+xo4fCIrDlA7DNMKWL9/+7dTOOY3p1QARHj+6apFfYnAMMiDI3LwnTlEO7O3pKcpc5rOmUA+hCZh9GEZ/pjLTpADQrjQTrVL7rxS5ZqqT5/wZ+n225m/s+IGgOEzpMEwjrPrx7d8ZU5/pMLzwt12v1YuTnkT/GGRA4Oj2rVrp+WeDFiDfBt6+A/2ZykyTAkDo1wp3N7wkKCa41RUMyt/Y8QNBcZjSYZjG6NxZz0loeDVAOLPkXp09SfYn+sMgAwK79Fv68nXPPxtWmqk0nFz+xmQu9dQ6/ftGUzaa8fzz45s2icnMsiXo99qav7HjB4LiMKHDMI1826x7B7FtFko802F45W9nwL96E/1+icUZVEDAS2nBhKB3V18mBJDj1dDpraaGjm8qVapLV39j054QhCeO9eXzM3cfif/n/j2lFoWmAJDgGiZ0GKYxfemaI/7cvMPwyt/xtaK8HJSZw75fYnEGFRAktm0XKyaLF/l2DVsUOnX8FPpzlZWmBIDRRQt9TQl45kDT3cfo99uSv7HjB4LiMKHDMI3xNWtEcPbBB891GF75O33lhkj6Hz4I/X6JxRlUQBB5b5Lvh4KgRqsqpzN19zcmecWO3l2tQ0GNvl0ntmSx9HmnFAASXEP3DsNEOtuz124912F45W/eEfe0TmeG4uj3THyeQQQEudQnTjUGP7dn4QQw35br01XqbTnd/Y1N57T50P6+Xid18ozIO2WTG+x7bsnf2PEDQXHo3mGYxvwBjS7P5WN5PUDYdThBcBr7vonPM4iAIG3r9E0Y4/v9wKCvUq1WHf2NTRAED6JcGy8z1/FNnnsKh06w77uUv7HjB4Li0L3DMI3JffvFVtn784p2GF76u6VrEfEZREAQW7VKpBts3Oj7/YDEDL/Wps3oz1ZGmhAARqZMDEyDFA6Z8GudlbPsJQWABNfQvcMwjdF5s61VucNFOwwv/e2sNvbtRttyEjKIgAByQIulG/jB1JnzYltuygT0ZysjdQ8AofJQEOkGNhObt4jVxhXL0e+9lL+x4weC4tC5wzCN/PRaHytB+nG0aIfhtb8bB/WxTss9Qr9/ov/+LiRIDPEJQI9OgehB8m05NvhDEJBLf4r+fGWj7gFg+sJlkW4wflQg18vnGw5Av/dS/saOHwiKQ+cOwzTa+lUQlJXqMLz2N0h/8NNyO3ai3z/Rf38X0q42A7mgQd1TeOxIseJ48Sr685WNugeAjvRUM3UDv8gPuvXoKCbUkRT6/RfzN3b8QFAcOncYpjGxa4/YslhUX7LD8NrfqWMnxbbc9PfQ75/ov78L6eix7d4b2D3F160LNAhQiboHgOHRw32rNlOKdsk5GfUnKQAkuIbOHYZpjMyeIfL/jhwv2WF47W8oxdTw7g+bGrq9S2XhJKPfAUHj4L6Bb/+nL1wK7NSxatQ5AMzFc6Kf6dq+KZcJbvsfdABFWbil6M+gmL+x4weC4tC1wzCNz+jyNSZLdhh++Ns+CJC5cRf9ORD99zfQyf/r2TnQA0C8Dmyndk0NHdvxEnHYz1gm6hwAps5csA4ATQz0utCn8bSaYQPRn0Exf2PHDwTFoWuHYRozN++3mrDs1wABRdMpD1A++hkQpI6eEAPyrOmB35ctzwEahNjPWCbqHABCyUm+9f/hh4Fel0+s7brqkTT6c2jub+z4gaA4dO0wTKNdKgtKGLXUYfjhb9hy5ocBZs9Afw5E//0NxAz6If+P8gCD9Tc2YcufB/0fXQn82pDfLGMeIAWABNfQtcMwjdG5lv7f4aMtdhh++DvbEKMyXRLSz4DA2fa/eS/w+7Krj0Qmj0d/xjJR1wCQ6//xbf83UapyJLZtD6T6SDX+xo4fCIpDxw7DRIb69xTbFI8iLXYYfvk7NKCXCAjuh9CfBdFffzsHf7p3QDn4w/UAnQMBn6E/Z1moawAIp375wZ+xI1GuD6UHeXrNyCHoz6K5v7HjB4Li0LHDMI35FbiWK3L4OUBAOTi+AnngEPrzIPrrbyjDxVfgpk1Bu7fGEYPp4FFA/sZmYvNmsQK3ehXK9WGSISqQvCHVwSMKAAmuoWOHYRqTR8vLwfNzgEju3SdsqF+A/jyI/vo7vnYNek3e2FIrB3HnbvTnLAt1DQBhohFU/d9SxMxBbMnf2PEDQXHo2GGYRshN4YPh9h2tdhh++dupQjK4L/rzIPrrb+cULuJgCLmufMIxdzb6c5aFOgaAz5zCjWbQ7IivsSc9m9CfSaG/seMHguLQrcMwkeFRQ8WAfO1Wqx2GX/7mdYjtskmIHTXRX3/DgAy5d5CDl0s8Qbs3yHXlaQ/9e6I/Z1moYwCYuftYTCyH9EO1I3XyjHQVjygAJLiGbh2GaYScFMhNgRyV1hTy/R4gIu9NEls1Zy6gPxeiP/7O3LL0JocPQr03PuHo201MOBpi6M9aBuoYACYPHhYrve/PQ7UjG05ZwuedpFE6oACQ4Bq6dRimEbbhyi2N5fcAQfpsctEPfyf37hcD8qKF6PcXnTNTTDiOnkC3RQbqGAA6epO79qDb0jioj1RKBxQAElxDtw7DNCa2bBVB15rVZXUYfvo7dea82CaZOhn9uRD98Xe0fqE47b3vAPr9JbZuE6dDV+GcDpWNOgaA4dHDRNB1/Q66LdH5c8X//sHD6LbY/saOHwiKQ7cOwzTCyV++CnLsZFkdhp/+hlJJfJukhzzbJCbTD39DTVQ+IN9+gH5/6YtXxer3xLHotshA3QJALgDd8U0uAp1Lt5zeEgRhFbK1aktB+xs7fiAoDp06DBNZjgB0YYfht79l2yYxmV772xFg7vYuigD0c/YkbEHod6SwB5u6BYDpq7dEgD9mBLotQNCc5PaMGopui+1v7PiBoDh06jBMYz4xuXNZK25BDBDRea2XpCMGQ6/9nb5wSQyAk+QpwdY4dICYcNx5hG4LNnULAKHOtEwl2OCQnVOSLv0Juj0UABJcQ6cOwzTCadtKcu6CGCBk67RNptf+Bg00nm+6bi36vdmMLpgvVV6WTv7GppNzJ9FkMjx6uDQ5iRQAElxDpw7DNMY3fFjRqdsgBoj01ZtSbduYTK/9HZkxFb0iQ3Mmdu0WE45lS9FtwaZuASCIysuWTgL5f/xU8u696LZQAEhwDZ06DNMIoqR8QD59ruwOw29/P5O43YouIdFfeu3vUJ+uIt+0MYl+bzZB/JwmHP74G5O5aMY6UNZRqgNlcPpdFhkkCgAJrqFLh2EiKx2QgxogGkcOETP3W/fRn5HJ9NLf2VBcDMh9u6PfVyHzE463jJ9w6BQAps5+JNJb3puEbkshMzctIXTWx2HbQgEgwTV06TBMI1Q/4ANyvx4VdRhB+Dtav0Dk7hw4hP6cTKaX/k6dPi9dKSybdilEOKWJbYsu/sZmfONGkd6yfj26LYXMZT7jk42GDm825VK4B0EoACS4hi4dhmlMnTgtBuSZ0yvqMILwt5OXRQdBUOmlv+MfVpZvGiRjixeJCceefei26OJvbEK/xtNbTpxBt6U5Id2gnNrrQfgbO34gKA5dOgzTGF+7VgzImzZX1GEE4e/05RsiL2v8KPTnZDK99LczIJ+Ub0B28rLq8fOydPE3NkMDepWtbxo0ZSlPRwEgwTV06TBMY2TKBDELPX+pog4jCH/nkh8Lgd4u7UmgF5Fe+tsRHH8cRb+v5oRcU56XNWIwui26+BuTuVhWygMgNpP7D1oTjgXo/saOHwiKQ4cOwzRCpwjiz3xAjmYq6jCC8nfj0P4iL+vuY/TnZSq98nfWPpFZpuB40BR5WbZAr7kHQXQJANMfXZFOcLyQUAaRTziGD0L3N3b8QFAcOnQYptE5kVnBARC7wwjK346I65Fj6M/LVHrlb1hl5vmmUyai31MpOgdBbt5Dt0V1f2MzsW27yCFetRLdlmLkE47Obzc1dHijKZd6iupv7PiBoDh06DBMY+pMdScygxwg8p34KvTnZSq98ndiy1aRb7p2Dfo9lSKdPNcnAJSxAkhzhseOFCk4V2+i+hs7fiAoDh06DNPolOSqUCIhyAFC9m0cE+iVv6NzZ4kDIEdPoN9TKSZ27hITjhXL0W1R3d/YbBw2UPr6znZFEMyT5xQAElxDhw7DNEbnzBQD8vFTFXcYQfnbSeTu3kHKvDET6JW/ZSzJ1ZzpS9fEhGPiWHRbVPc3JmFLFbZWYYtV5gNkEPjxCQcLBDH9jR0/EBSH6h2GibQH5OyDxoo7jCD93Tioj7DzYRj9mZlIL/ydiz/hPmzo9q7UgXwunjN+wqFDAKhKaT+n5vk4PKkrCgAJrqF6h2EaHYkVGJArnCEHPUBUu1JJ9IZe+FullbXGgb2l1Y5Txd/YlGFlrRw6/XDXd9BWKikAJLiG6h2GaUxfsUWWR1fVYQTp72pzFYne0At/q5RbF5klr1i1Kv7GplPVZe9+dFtaY7U7MV76Gzt+ICgO1TsM05jYvUcMyMuWVtVhBOnv1Olz4rTyjKnoz81EeuHv6KKFYkDefxD9flqjU65uwwZ0W1T1NzbDY4aLfNPrd9BtaY3R2TNQdzgoACS4huodhmmMLa4XA/K+A1V1GEH6G6pGcMHUgb3Rn5uJ9MLf+bqnt9HvpzWmTp216mNPQ7dFVX9jErZS8/p6n6Db0xrjGzei1semAJDgGip3GCbSzQw56AECkvEbunfg9uYST9CfnWl0628+IHdtz3OdIOcJ+35aoz3hgDqy2Lao6G9sZu41iAnj0P7otpRDZ8KBtMNBASDBNVTuMEyj2xkyxgABuYp8BenKDfTnZxrd+htym/iAPLgv+r2UQ14isUcnMeGIZdHtUc3f2IStVF5jd84sdFvKIfaEgwJAgmuo3GGYxszdR2JAHjaw6g4jaH/Hli5BF0w1lW79nTpxRqxwzJqOfi/lEoTH+YTjoyvotqjmb2xC7ibfUt24Ed2WcsgnHPYORzyH4m/s+IGgOFTuMEwjVGLgM+R5s6vuMIL2tyPrsGwJ+vMzjW79reKhCjitDDYndu5Gt0U1f2MzYh+qOKHOKW6QR+ITjkvXUPyNHT8QFIfKHYZpBDkVPiBv2lx1hxG0vx3Zmglj0J+faXTrb+xTjtUQDkfxCcfiRei2qOZvbDYO7ocqq1INY8uXoU04KAAkuIbKHYZpjMy0dM5Ona26wwja304lCYMrNGDRrb8bh/STvgRcc6avWpUkxuNVaFDV35jkJeBAWLlLe6lLwDUnyCPxXZlFC1H8jR0/EBSHqh2GiXSER6ssrYY1QDQOsCo0PI6iP0OT6MbfcMiID8iS12R9zu6EuRMOlQNAUDUQJeCGo9tSnd3Bl66jAJDgGqp2GKbRmSF3rX6GjDVAgEwCX7k8fR79OZpEN/52BrbRag3IQDiVySccDTF0W1TxNzaTBw6JlbT64FfS3PCZ0pwBTzgoACS4hqodhmnM3LjreoaMNUC4zV0kBu9vVQdkYGT6e2LCcfYCui2q+BubsVUrRS7d9h3otlRKpwZ1wDscFAASXEPVDsM0Jg8etgbkBa46DAx/p46dFLbPre70MjF4f8dWWgPyjp3o91Ep42vXCNu3bkO3RRV/YzMyZaI4TXvhErotFdtuTzjOBLvDQQEgwTVU7TBMY2z1KtczZKwBInPvsaXwPwD9OZpEN/6OTJ5gDciX0e+jUiYPHxUTjgXz0W1Rxd/YDPXpJlbRwil0WyplfO1a0Tdv2Rq4v7HjB4LiULXDMI2RqZPFgHzuoqsOA8PfvIJJp7eaGjq+2ZTLfIr+LE2hG3+HencVA3JEvQE5c/O+SJcYNRTdFlX8jclsNCMqavTqgm5LNcSacFAASHANFTsMExnq10MMyKGEqw4Dy9+NIwYLSZE7j9CfpSms1t+wCsMH5D5d0e+hGubSn/ByiaqdYMbyNzahaguvODN5PLot1TBz8x7KhIMCQIJrqNhhmEYoM8QH5B6dXJ00wxwgoHoJz5M5dhL9eZrCav0NeVh8QJ4yAf0eqmXjkP7KaRhi+RubIEsYQ4QAACAASURBVKLMxbtXLEe3pRpyySSECQcFgATXULHDMI3py95U08AcIKC+p2plxVRntf5O7NwlBuSVK9DvoVpGFSwrhuVvbMYW14t64fsOoNtSLZ0qJg+Dq2JCASDBFR61f23gZ4f3K9dhmMbkXque7lJ39XQxB4jUidMiT2bOLPTnaQqr9XdsyWJrQN6Pfg/VEiYafMLBJh7Ytsjub2yGx44U+c3XbqHbUi3dVmmq1t/YMQRBYTx+5/UnIGL5JP0UvQERS9OpN7l7j+sOA2uAcE4CDxuI/jxNYbX+hpVmPiBfvoF+D9US6hcL6SFzJhwqBoCQ0gIiyjAOgagytj3VEkPrlAJAgis8bv/6JZ4nc/MuegMilmZ40jgxIF+65rrDwBogcpnPmho6tbNOAn+G/kxNYLX+DvXqzP/fcrEs+j1USxMnHCoGgFCthec3D+iFbosbJo8eFxOO+XMD9Td2DEFQGCwAXMOXrY8cRW9AxNJ0BuRoxnWHgTlANA4fJBLz79JJ4CBYjb9B9kXlE8A2hfQQm3B0YBOOtBnSQ9jtuxqCrBU/cDR1Mrotbpi5/UBMOEYOCdTf2DEEwWe8+uqrNXV1decZH9XW1l5i/F7z99TU1PwNe/0njNcZb8BX9tqvt/bZj99+fShftl6/Dr0BEYszG05aA3I3TzoMzAECtuP4hOP4KfTnagKr8Xf64lVx4GiSmpIchYTBmE842OCMbYus/sYmVJrh+c2rVqLb4oYwyYDdDdA7DeokMAWABoAFfsdZMPc2fM8Cu++zny83f48VAF6v9LMb3n79H/my9azp6A2IWJxQiUFoZLmX5MAeIOIffmidBP4Q/bmawGr8ndxjHTha5u7AkQyE7Tg+4Th6At0WWf2NzdjiRcqfALYJlY74hONeQ2D+9iLGIEgKFti9yAK7H7Fvv26/xgLADGPbZu+DAPBGpZ/f8M5/e5UvWw/pj954iMWZ2LVHDMjLl3nSYWAOECYm5mOyGn87B47Y/x22/W5pmvQQdvuuhjocOLIZnTPTkh46HZi/PQgzCLKCBXZ/xoK9B4WvwTYwe/1vm70PAsDP2XuvWr/vUc7nb3nttW+EoERXByrRJStjy5ZaJ4D3etJhYA4QmbvmJeZjshp/g/gzH5A/uoJuv1uaNuHAbt/VMNRT/QNHNh3poQ+D2eGgAFBzFAsAYQu4eQD44osv/tY3v/nN37Z+/4eMt9h7/qmca8RGDxUClvce8X8oolyE8kh8W+HiFdef9fSpGCDgK8a9PMl+JvJkOrbj32M/W91Zjb9DfbuLATmcRLffLbN3H4kJx4hB6LbI6m9M5qL5A0fYtnjB1In8hCMof3sWbBDkQ7lbwEX+bjj7u/nlXCOzaD7/p/3xlUtNBPkQGSBqAP/i8x9hm+IJYqNETeCfZ1LYphCa4Zc/+WcRMPXq3PTVV19hm+MaX/3iF3zCEer8VtNXv/wltjmEZvjJw/si/2/6JGxTPMHPU+LAXmzMsMCu6TLEIMgOFuydYHwHvodVvWKHQNq0afP77MvX4HtYCWTvOccCwHfL+fxPdm0TW4wbN6LPoIjP8kniiVUDuGPTkyefezJjBGCuEDgngdlsGfv56s5K/Z25dkucAB4/Ct12r9g4JF+iC9sW2fyNTafC0bIl6LZ4wSeZT52awE9yPwrE317GGgQJ0bZt2zoWzF0AGRhr+/eP4HX2/XL2+j/A9+y1Xuz7u5YEzB3GMeV+/o8vfySWrefNRs+hID7LtD0gjx3pWc4IgHdWSPdkYokuLFbq7+T+g2JAXlSPbrtXjMycJiYcp8+h2yKbv7Gp04Ejm05N4EeRQPztV9xBMAQ/TyYCF7AklsfkwcMiOK9f4FmHgT1ApI6dtPJkaMLhNyv1d2z1KjEgb9+BbrtXjK9dK+5py1Z0W2TzNzZ1OnDk3NOMqWLCceZCIP7Gjh8IioPnyVjL1kEJWBLLY3ztGjF4bd3mWYeBPUBk7liJ+cMHoT9f3VmpvyPTpojB6+xH6LZ7xeTBI2LCsfB9dFtk8zc2Q/1EfnO2MYlui1eMr1kd2CSKAkCCa0CHUZgng92AiHl6vX0lwwCR43kywSrmm8pK/d04oLfoBx5H0W33ipnrdzxNo5CZMrTvcpmL5/Obc7nP0e3xik4axWL/0ygoACS4BnQYUYPyZFSiE5g/8CYwl2WAaBzc15pwhNGfsc6sxN+51NOmhnd/2NTQ9R2tBuRc8mMRaHTvoNV9ufU3Np385nGj0G3x9L6u3BD3NWFMIP7Gjh8IigM6jPg6c/JkVKEfK2WyDBCR6e8FlidjMivxd+bGXTFwjR6ObrfX1HGr0a2/sZk8cEhszS9aiG6LlwRBaz7h6NUlEH9jxw8ExQEdRuqwOXkyqjBz1/tcOVkGiNgq/Q4byMhK/J08fFT0Ae/PQ7fba0amTNTusIFbf2PTyZXbth3dFq8Z6t1ViKlHM777Gzt+ICgO6DAyN63Z/5gR6I2HKOiUsZrjXRkrWQYIKPwu8mQWoT9nnVmJv+Pr1okBefMWdLu9ZmzFcu3kRtz6G5vOLsBZ/XYBwhPHBlLfmAJAgmtAh/Ek9bHI/+n2rvZ5MqrQKWT/wQeedhgyDBDpy9fFhIN1lNjPWWdW4u/IzOliQD51Ft1ur5ncYwsOL0W3RRZ/Y7NxUJ/A9PKCJkxseYWT/Qd99zd2/EBQHHaHEerf04g8GVUYnT9XdCJHjnvaYcgwQGQjaacGKPZz1pmV+LtxSH9Rc/p+CN1ur5m+eJXfG9TVxrZFFn9jMpf+RCw4aCo9BqktfMKxepXv/saOHwiKw+4wHFFO1lliNyDiF03hUUPFgHzzvqcdhiwDRKhnJ5EnE8+h26Iry/U3DMJQM7ehYzstB+RsOCUmHH27odsig7+x6WiBjhiMbosfBB1NPuGY/p7v/saOHwiKw+4wYHuErzjt3YfegEwnbMM3dG3PZ8m51CeedhiyDBAg/8AnHNduoduiK8v1N6z68QF5aH90m/1iqIf+Ew6Z2ndLTJ047Xl+s0yEbW3engb18d3f2PEDQXHYHUZi526xbL1yJXoDMp0gxMs7kAG9Pe8wZBkgoLwdn3AcPIxui64s19+p0+fFisWMqeg2+8XweGvCcVXfCYdM7bslJjZvFvnN69ej2+IH+Yp657d5hS3Y7vbT39jxA0Fx2B1G6txFMQhMm4LegExn3heTPe8wZBkgQHOSDwLr1qLboivL9TdIcXBfrFmNbrNfjNYvtCYcR9BtwfY3NkFujPvikL6+aBw5RKTw3Hnoq7+x4weC4rA7jKCWrYmtM7Fjp1iNXeXtaqxMAwScNuVB7qzp6LboynL9HdSpRUw6Ew5NV50q8Tc28+kft9Ft8YvRubPFqfrjp3z1N3b8QFAcdofx7LL1p+gNyGTGliwWA/K+A553GLIMEJl7j8WEY9hAdFt0Zbn+zuuWXUe32S+mTp6x8s5motuC7W9smnAALL7hQzHh2LjRV39jxw8ExVHYYUDVCb5sffcRegMymeFJ48SAfMnbAVmmAYKXuoOTp530PHkqA8v1d6hPNyEBFUmh2+wXnco6mp48rcTfmMxGM0ZIQKWOnhATjvlzffU3dvxAUByFHQbMjvmy9Ykz6A3IZDq1S8PeDsiyDRC29lz2QSO6LTqyHH/nEk/EgNyjI7q9fhJ2NWB3Q1ftuXL9jU2ojsFF4CeMQbfFT2Zu3Rf3OWqor/7Gjh8IiqOww4D8GF3LQanCXOop94EfVVlkGyDg1CmfcJw+j26LjizH35nrd8RANXYkur1+06k+8TiKbguWv7EJeaY8v3lRPbotfhLku7jYddf2vlXXogCQ4BqFHQacyuLL1gvfR29ApjJz+4FvM0fZBoj4mjViwrF1G7otOrIcfycPHxVtfsF8dHv9Jpyq56kV5y+h24Llb2zG15rT5kHGy88JBwWABNco7DDgVBYPPsaNQm88phJOjfEBea73IqmyDRCmrAZgsRx/Q61pnqy+aRO6vX4ztmK5CD527UG3Bcvf2HRqTp8+h26L7/c6dZKYcFy47Ju/seMHguIo7DDgVBbPB+rZCb3xmErYfvdLrkK2ASJ9xYx8ICyW4+8g5CpkYWL3HjHhWL4M3RYsf2OzcegAcdDwXgO6LX4T/s/4hGP3Xt/8jR0/EBRH8w4DTmfxZetoBr0BmcjoIluw1vsKGbINEDn7RGCvLui26Mhy/O0I1t5+gG6v34SVGK49OXUSui1Y/sYklxrr1I6f/s9lPkO3x28mdtnVtVb45m/s+IGgOJp3GHlNsBvoDchEOs//ivfPX8YBItSrs9AEi2XRbdGNrfn7mZrTPpaskoXZhpgvJRZloYzt+5nn/7BRPP8h/dBtCYJpn6trUQBIcI3mHUZscb32VQFkZqivf5psMg4Q4fGjrRqtN9Ft0Y2t+dsOiEIDeqHbGgR5wNtF34BXxvZdyNSZC9rXnC6kU11rcF/f/I0dPxAUR/MOI18XdA16AzKNueTHQgKmewdfpANkHCCcLe8Dh9Bt0Y2t+dvZEn1Pzy3RYszXaNVP7F7G9l3IxPYdVonLVei2BEGx5f1WU0OHN7nwvR/+xo4fCIqjeYcBmmx8UJg5Db0BmcbMTUs8dPQwXz5fxgHCqdG6bi26LbqxNX/rfiiiGKNzZlli96fRbQna39jMl7jcj25LUIRSl34deqEAkOAazTuMzP2QWLYe2h+98ZjG1LGTQgJm3mxfPl/GAQKqzuheoxWLrflbd1mUYtRZ7F7G9l3IfInLa+i2BMW87I33YvcUABJco3mHwZetoUZrR6rRGjQTmzeL1bAPPvDl82UcIDJ3HmpfoxWLrfk7r1OmpzByMeosdi9j+y5kqG93X0pcykxH7H77Dl/8jR0/EBRHsQ7DrtEKq4HYDcgkRusXiC0SNkj58fkyDhCQjM9LJnXxr2SSqWzN340D/a1UICMdsfvx+ondy9i+bdr5zSGf8ptlpSN2v2SxL/7Gjh8IiqNYh0E1WnEIgsh+noiVdYAI9e8pApFQHN0WndiSv00NvEFuSIjdd0a3JUh/YzNz464IvMcMR7clSKYvXRf3PWm8L/7Gjh8IiqNYhxFfs1osW2/bjt6ATKLfItyyDhCRyRNE4PvRFXRbdGJL/na23kcOQbczaILwONee1EzsXtb2DUweOSa23t+fh25LkITtbj7h6NfDF39jxw8ExVGsw0juO+DbsjWxOHOJJ6Kj6NHRt2vIOkDEli4RW997zTkdGARb8jecgvWr5rTs9HulXUZ/YzO+YYPIb964Ed2WIMm1J7t3EBOO5Mee+xs7fiAojmIdRvriVSEFM9n7ZWticQaxRSLrAOHog602Qx8sKLbkb+fAkQ81p2VntN6/couy+huboGzA04qOnUS3JWiGRw8XOfU373vub+z4gaA4inUYkIvFV6P690RvPKbQkYCZP9e3a8g6QKTOnDeqQkBQbMnfcAqWB0GHj6LbGTR11Z6UtX0Dw6OGiiDolrdBkAqEPt2P4JcCQIJrFOswnqkRmtKvZJKMjG/aJAalDRt8u4asA0Ree3IAui06sSV/h8eNEtug126j2xk0Uyct7cnZM9BtCcrfmBTjyTtiGzT1FN2eoOlsf7M+3mt/Y8cPBMVRqsMAXTZRMukhegMygUGsyEg7QGQ+4+WSGjqR9mRQ/g716iwG5HgO3c6gmbn7SEw4hg9CtyUof2MyG076dhBCBToHYBbM99zf2PEDQXGU3CJis2NRMukMegMygaBLJlZkbvl2DVkHCCAUTOcnoB9F0G3RhaX8DUEfH5B76SeFUg5z6U/ZhOONpobOb2s14ZC1feelUMah24LBzPU74v7HjvTc39jxA0FxlOow4mvXCimYLVvRG5AJdKQpYlnfriHrAAGMTJssAuBzF9Ft0YWl/O3XgKQSGwf10U4EW9b27YghL65HtwWDubil8NCzk+f+xo4fCIqjVIfhNNpFZjbaYDuInC8dRLEOQ8YBApivS7sb3RZdWMrfySPHjdRkK2Rkqn4TDlnbNxy2MX0xwQ+NVwoACa5RqsNwlu0njkVvPLrTkYDxeUVG1gECmNi1R0w4WCCIbYsuLOVv0GLjSekffohuIxZjy5eJoGT3HnRb/PY3NqNzZhqfTuSH9iQFgATXKNVhOIm7fbujNx7dmTwazIqMrAMEEFZiuBTM1MnotujCUv6G/zN+4OjIcXQbsZjYuVtMOFauRLfFb39jE6rNmH6gMLrI1p70rs47BYAE1yhZKxSO7nd71xcFc+KzdFZkNvi7IiPrAAGEwx/8ZOagPui26MJS/rYlYCAXENtGLKbOXhATjunvodvit78x6UjAGC4p5mhPeii8TgEgwTVa6jBMFu8MkvkVmWO+XkfGAcImnMZs6PQWl4PJZT5Ft0cHlvK3IwHj44Ej2Zl90CgmHEP6o9vit79Rn3Oj2RIwNmH7m+/yzPGu9CIFgATXaKnDgDqhPHfj+Cn0BqQzIfcviBUZGQeIQjYOGyiew70GdFt0YDF/5w8cmSkB4zwHW3uyoz7akzK277wEjNllRTN3LO3JkUM89Td2/EBQHC11GLBczROlN29Gb0A6EwbjIER5ZRwgChmZOU1MOE6fR7dFBxbzN0nA5Kmb9qSM7dt0CRibufQnfBu8oUt7vi3ulb+x4weC4mipw4Bi6XzZun4BegPSlbANF5Qor4wDRCFjq1eJCcf2Hei26MBi/g7qwJEKdLQnz19Ct8Uvf2PT0ZPdug3dFmw2DugtJhwNcc/8jR0/EBRHSx1G+soNsVowYQx649GVzorMuFG+X0vGAaKQyX37xWrBksXotujAYv4mCZg8dZOCkbF9OxIwJ82VgLEZmTJRTDguXvXM39jxA0FxtNRhZCNpsTrVpyt649GVTp3IAFZkZBwgCgkdIz+ZOXkCui06sJi/oR5pEAeOVGBeCmYFui1++RubJAGTZ2zpEtH22ETXK39jxw/GoK6uLsOYbo3YdlaK1jqMUPcOIj8t8QS9AelIkH7hKzIbN/p+LRkHiEJmQwkx4ejfE90WHVjM3yQBk6duUjCytW8hAdPeeAkYm5Dawvv6NWs88zd2/GAMampq/qYcYttZKVrrMMKjh4sB48Zd9AakI6Pz54pZ4VH/RXllGyCakwYM//0dRM1pVaibFIxs7duRgKEJHWfq9Dkx4Zg9wzN/Y8cPBMXRWocRnTdH5HAcPYHegHRkeMyIwAJs2QaIYnS2jG4/QLdFdTb3N0nAPEsuBdNRHykY2dp3+tI1koApYObuYzHhGD7IM39jxw+m4tdqa2snMTYyfg4v1NTU/Je6urre2IZVitY6jPgHHwS2RWkiQz07WRIw/m+xyzZAFCMIpYq6oafRbVGdzf0dVM1plaiTFIxs7TsvAbMI3RYZmEt/6qkUDAWASGDB3gIW7B1k/CsWAP4IXnv11Ve/w76/i21bpWitw0gePioOKSyYj96AdGNeAqZLINeTbYAoxvi6deJk5pat6Laozub+JgmY5+lIwZy7iG6L1/7GJknAPM/QgF5iwhFKeOJv7PjBSMBhDxYE/mvr+0/t1+1gUCW01mGkr90KTKbENDrPdnwwz1a2AaIY89qTC9FtUZ3N/R1UzWmVqJMUjGztOzp7hljNP3UW3RZZCAoHXknBUACIBBboJb71rW/9K/jeDgDbtGnzu+z7KKphVaC1DiNIoWLT6KyuLnw/kOvJNkAUI2lP+udvkoB5njpJwcjWvhtHDLYkYB6h2yILQeOUt8H9Bz3xN3b8YCRYALiEcSUEgVYA+A328yLG+di2VYpyOox8npq/pcpMo5NfuWlTINeTbYAoxrz2ZDd0W1Rnc3/DSjNffbh2G902WZg6+5E2UjAyte9nTvSn6US/zcS27aLPX7vWE39jxw9G4pvf/OZvs2BvOwv+/oV9/SXjz+DnF1988bewbasU5XQYkDRO2mHe0zlhfexkINeTaYBoiY72ZPJjdFtUZnN/kwTM89RJCkam9k2ansUJ2+F818cDKRgKAJFRU1PzYtu2bf/8lVde+Ra2LdWinA4DksbF1pH/WnUmMTzG0li8eS+Q68k0QLT4XEYH+1x0ZaG/4ZS5kIDphG6XTNRJCkam9p2v6kMSMIWE7XA+4Rg5xBN/Y8cPxoIFfr9TW1v7JuMQ+Ao5gNg2VYNyOgyoG0r1Q71nqEfHQKusyDRAtMTovNmBrozqykJ/kwRMaeoiBSNT+3YkYKiu9zOE7XAuBdP1HddSMBQAIoEFfH/N+Bnj9bq6up3s6zX4WcdKILwxHyH5CK+ZjWYCr7Ms0wDREvO5kZvRbVGZhf4GIXfehufPRbdLNuoiBSNT+46vXSNOV2/bjm6LbIRtcT7haEy69jd2/GAkWLB3hwV+7QtfY8Hf2zrqAAIh949WD7xl+urNwE+7yjRAtMTkoSOBno7WlYX+JgmY0oytWK6FFIxM7TtCEjAlCZVR+ITj0nXX/saOH4wEC/6+YF++3uzlb1ivK4VyOgzKH/KeyYNWkFO/ILBryjRAtMT0VVsfcTS6LSqz0N8QTPM83sNH0e2SjbpIwcjUvh0JmLskAdOcUBmFt8UDh1z7Gzt+MBIs0FsPeX/NXvsh4zosm6pFuR0GnSD0lvH168Wqw+bgtjllGiBaIsb2uI4s9DdJwJSmLlIwsrRvLgHThSRgShEqo/DV+HXupGAoAAwQLODbyPihRS4Bw3jF+v6KJQmzDdvOSlFuh5EfQG6hNyAd6Bx0OH4qsGvKMkCUw6APyOjIQn+HenelCVwJ6iIFI0v7zobiJAHTAlMnzojdnzmzXPsbO34wBjU1NePKIbadlaLcDoO2kLxlePQwS+rkfmDXlGWAKOv52BI5N+6i26IqbX8/SVAKR0vURQpGlvadl4CZgP5MZGTmzkNPpGAoACS4RrkdBlSr4MvWH3yA3oBUJ98iQRA7lmWAKIdwWpWvkB49gW6LqrT9nblpScCMGYFuk6xsHNxPeSkYWdp3ct8BkoBpgbmUJQXT7V1XUjAUACKiTZs2v1FTU/Mfamtr/459/Xub2HZVinI7DNBkIxkJb5iNpMSKTN9gy53JMkCUQ0cKZuNGdFtUpe3v1DGSgGmNOkjByNK+42tIAqY1hvr1EBOOcMqVv7HjByNh6QDmoA4w+/olfGX8BWMY27ZKUW6H4QjJjhmO3nhUZ/ryDfEsJ44N9LqyDBDlEFINSArGG38n7NX7DRvQbZKVjhTMrj3otrj1N3b7JgmY1hmeNE5MOC5XLwVDASASWKB3lQV+feF7EIC2vo5iHIxrWeUot8PI2XlEPSiPyC3h+D8PbhYtDPS6sgwQ5RAOGwkpmFHotqhK298xyt9tlTpIwcjSvhuHD7IkYB6jPxNZGVtU71oKhgJAJBTqANoBIMOvsddTeFZVh0o6DOckYTSD3oBUpiMBs2VroNeVZYAoh3BalU84enVBt0VV2v4GPUU6wd8ydZCCkaF9PysB8yn6M5GV0PfzVXk2FrjxN3b8YCRY0Bf77ne/+3vW9/dramr++OWXX/4D9v3n2LZViko6DGcguUoDiRtG584KXALG7jCwB4hKCKdW+YQjnkO3RUXa/qaJW+vMPlRfCkaG9u1IwAzohf48ZGbqxGmxCzS3eikYCgCRUFdXN5sFe29Y3w9ifMqYYVyObVulqKTDICkYbxgeNVRskdx+EOh1ZRggKnpOY0aQFIxLf//ypz+l1I0yqIMUjAzt25GAmUISMC0R+n6e4sLGAjf+xo4fCC/wIPCvXn311f/6wvPl4aRHJR0GScG4J98i6fauWJFJPQ302jIMEJXQloJJHj2ObouKBD//LBohCZgy6UjBPAyj21Ktv7HbN0nAlEeQ/4Ln5EYKhgJAgmtU0mGQFIx7ZsNJsSLTr0fg15ZhgKiE8Q0fkhSMS3//+PJH1GbLZGTaFKWlYGRo344EzPYd6M9Ddob6dhcTjkh1UjAUAAaI2trajxgvtEZsOytFJR0GScG4Z/rSdfEMJ40L/NoyDBCVMHnkmAhe3p+HbouKBD9/sncnScCUSdWlYGRo35FZ00V+8+lz6M9DdoIMGJ9wXLlRtb+x4wdjUFdX9045xLazUlTSYZAUjHvaEjCxxfWBX1uGAaISpq/dFsHyOJKCqdbf2RWLKW+3TCZ2qS0FI0P7JgmY8hmtXyja5sEjVfsbO34gKI5KOww6UeiO8XVrUSRg7A4De4CohHkpmM7otqhI8HNiyjiSgCmTqkvBYLdvkoCpjInNW1xJwVAASHCNSjsMkoJxx+icmWKL5MSZwK+NPUBUw1DPziQF48Lf4X7dacJWJvNSMP3QbanW35jtO9sgJGAaB/RGfxYqEGTAeIrLvNlV+xs7fiAojko7DJKCccfGkUPEFsmdh4FfG3uAqIbhsSPF87p+B90W5ZiklI1KqLoUDHb7zkvATER/Fiowc/O+SHEZPaxqf2PHDwTFUWmHQVIw1ZNvkXS1tkhSnwR+fewBohrCARA+4ThCUjCVMnvrHh3aqpAqS8Fgt+/kvv0ih3LpEvRnoQJtKZhQ9w5V+xs7fjASNTU1LwZ1rVdffbWmrq7uPOOj2traS4zfK2FTJ/a7x4wNjEvZS98o5/Mr7TBICqZ6ZkMJ0eD790S5PvYAUQ3jH1pSMOwrti2qkdpq5YxMm6ysFAx2+yYJmMoZ6tNNTDiqSNGgABAJLMD6GeMexu+zH3/Vz2uxwO84C+7etq77ffbz5ebvacMAdYjtwJS9bzf7vkc5n19ph0FSMNUzfemaJQEzHuX62ANENYSVP5KCqY6JzZvFgLyBVuvLpcpSMNjtOzJ7BknAVMjwhDFWTv3NqvztbbRBKAss3vp9FmQNZkHXLasMXH3btm3/3OvrQEDHrvOjFwoqjFgl59oWvg9sYVxk/wxVSdjPZ8q5RqUdBknBVM/k/oOWBMwilOtjDxDVEHL/eNA8diS6LaoxVi/ydVOU8BdMkgAAIABJREFUr1s2EzvVlYLBbt8kAVM5o/ULRIrLocqlYCgAlAAsSPsPLCCbw5hmQdd99vMwr7aI2ef8GfvcB4WvwTYwe/1vm732Ply34Ofvsb+LlnONajoMkoKpjvG11hbJ1m0o18ceIKohnP7lE46eJAVTKe0T+xmSgCmbKkvBYLZvkoCpjvFNm6vOqacAUAK88sorf8qCrdnWytxVFnxtZ/ycBWQ93X52sQAQtoBbCwDZ939USQD49Kn4ZyqXhQNLJX9nOqPWFkn61FmU64Ofq/E3NkEHEJ7bk3gW3RaVGOrT1XpuGXRbVGFeCqY/ui2VErN95xptCZhe6M9BJebzdOdU5W+3MQahCrCg71ssyBoIW8As+MpCANi2bds/sX8PK3DW1q0rBLUFXCns6gJfXDhbzZ8bi9joofy5/TyVxDZFKSQmi5JJPw2HsE1RBr/86U/FgNyzE7YpSuGrL78UUjCd2jV99ctfYpujDH7yUEiaJGdMxjZFKfwsFhUrgBNGVfX3bmMMQhVgwdVPWRC2iwVa/439+CvF3sN+v8KLa7HPOWGXmGMB4T8VOwTy8ssvv8JsSjJ7/g378WvWIZCyViDhn6jSGWPCkoKB5HLsGZQqfPIkv0XyJPMJig2qrgDGFswXuWxHjqLbogptCRgYWFTzNzZtKZjcowi6LZUQs307+c1LF6M/B5VYqNVZjb+9iDEIFQJWAIO6Vtu2betYQHcBZGCs7d8/gtfZ98vZ6/9gv8+SgQmBDAz7ftkLPsnAAFNHT5C8RIXMhuKoEjB2zkg1/sZmfONGEcxsICmYcmlvLWWWLFDO39hUVQoGs307+c3btqM/B9VYbU49+NmnsINgCqrpMEgKpnI6KvmTJ6DZoGoAmDx6nCYcFdJOLv9k51bl/I1NRwpm9x50WyohZvu285tTp86iPwfV6JRXrfCwFgWABNeopsMgKZjK6ajkL1mMZoOqAWB+wjEC3RZVaJds/OL8WeX8jU1VpWAw27dT4vLuI/TnoBqrLa9KASDBNartMEgKpjLG16xGV8lXNQDMxWnCUSltgdmfNjYo529sqioFg9W+nylxmQ6+xKXqdMqrbthQsb+x4weC4qi2w3CWra+Sxlg5jMycjq6Sr2oACKQJR4XPy5KA+fLHP1bS35jMPshLwWDbUgmx2ne2MYme36wyq82ppwAQEXDoAsq0Md6Gn2tra/+avfY6tl2VotoOo9pla1PZOGyg2CK5h6eSr3IAGB4/qqo8GRPpFJnv0VFZf6M+v8xnQgqmY7umXPZH6PaUS6z2nb503cpvxilxqTqrTXGhABAJLNAbxwK+a+zrW7be36uvvloDr2HbVimq7TCcZesqFMxNIwwiDZ3fRlfJVzkApAlH+czcFBIw4dHDlfU3NhsH9+XPMPsogm5LucRq39glLlVntSkuFAAigQV6MagHbH3/mfXy1wq+VwbVdhgkBVM+sw0xSyW/N6odKgeANOEon4XVBVT1NzYdKZjzl9BtKZdY7Tu+bi1qiUsdWE2KCwWASIDqH+zLr8L3dXV1n8LXl1566TfZ9ylUw6pAtR0GScGUz/RHV8QWyZSJqHaoHAA6Qc28Oei2yM7C+qKq+hubseXLlJOCwWrf0TmzRH7zyTPoz0BVVpPiQgEgEligt4kFgROt73kAyH4eXVNTsxbXsspRbYdBUjDlM7l3n9giWbYE1Q6VA0CacJRPe7s8dfiIsv7GZl4KZiW6LeUSq307EjB3HqI/A1VZTYoLBYBIgEogLOC7BCt+jL9gDMPPVik2peCmw6CTmeUxtmqVWE3YsRPVDpUDwPyEoyO6LbLTloDJXLulrL+xmTp7QTkpGIz2zSVgur0r8ptTJAFTLauRgqEAEBdfY4HfX9TU1LzGgr+/ZD9/HdugauCmwyApmPIYmTFVrMicOY9qh8oBINCWNsnShKOs55SLZZT2NyYdKZih6kjBYLTvbNiSgOnXA/3+VWY1OfUUABJcw02HQSczy2Pj0AGWBEwDqh2qB4D2ylb66k10W2RloQSM6v5GfY4gBdPhzaaGTupIwWD4O31ZSMCEJ41Dv3+VWU2KCwWASKipqfmj2traw4xPGH9i8afwFdu2SuGmw6CTma2TS8B0eosNJm+wQQVPAsbuMFQOCKL1C8SE49ARdFtkZaEEjOr+xqZqUjAY/k4eOCRyJRfVo9+/yqwmp54CQCTU1dXdYsHefBYI/p/s+/+tkNi2VQo3HQZJwbTO7OOo2Eoa1AfdFtUDgsLTrdi2yMrC09Kq+xubkalqScFg+Du+bp3Ib96yFf3+VWelOfUUACKBBX+fsy9fw7bDC7jpMOhkZutMX7gkksmnTkK3RfWAIB/czEa3RVYWBsmq+xubeSmYvei2lEMMf0fnWhIwJ06j37/qrDSnngJAJIDcCwsC/w7bDi/gpsMgKZjWCYMH3yJhgwm2LaoHBJmb963tzWHotshKJy/30BHl/Y3NxM5dSknBYPg7PGqoyG++/QD9/lVnpTn1FAAioU2bNr9bV1f3kPEACwRXFRLbtkrhtsMgKZiWCYMHX0Vggwm2LaoHBM4Bh+4d0G2RlfmDMreU9zc2HSmYGVPRbSmHQfvbkYCB/j/1FP3+VWelOfUUACKBBXrbWPD3CPIA2dephcS2rVK47TCcZesKFMxNIuiICQmYC+i26BAQhPp0E4n5kTS6LTLSkYBhEzId/I3JzP2QUlIwQfs7G0mJCVnf7uj3rgMrrXZEASASWKD3P7773e/+HrYdXsBth0FSMC0TBg++RcIGE2xbdAgInBWuKzfQbZGNzcWydfA36vNUTAomaH9DG+QpGRPHot+7DnRO8JeZU08BIBJqa2uvtWnT5vex7fACbjsMkoIpTSEB044PIjCYYNujQ0AQrV8oJhwHD6PbIhubDyA6+BubcHpfFSmYoP0NbZCvWC1aiH7vOrDSakcUACKBBYCD6+rqrjC2r6mp+ftCYttWKdx2GCQFU5owaPAtpMF90W2xOwzVA4LE5i1iwrF+PbotsrH5FpIO/samIwVzQX4pmKD9DW2Q5zezNol977qwkmpHFAAigQV+kRIMY9tWKdx2GCQFU5rpcxdFEvm0yei22B2G6gFB6vgpEeTMJSmY5my+Gq+Dv7GpkhRM0P6GNsjzm1mbxL53XVh4iKscf2PHDwTF4bbDyMVJCqYUE7v2CBmJFcvRbbE7DNUDgswtSwpm1FB0W2Rj83xcHfyNTUcKZpX8UjBB+xvkmHh+M2uT2PeuCwtlnMrxN3b8YDRefvnlV9q2bfsf2zBg21ItvOgwSAqmOCHwExIwu9FtsTsM1QMCWwoG5CdAhgLbHpnYXEhWB39jUyUpmKD9DXJMvN9nbRL73nVhJdWOKABEAgv8/qCuru4s478wZqyv577zne+8hG1bpfCiwyApmOJ0JGDOfoRui91h6BAQgOyEkIJJodsiEwslYHTyNybzUjAD0G1pjUH6G2SY+M5Pn27o960TK5GCoQAQCbW1tTsYF7344ou/BT/DVxYA1jPuwratUnjRYZAUTHE2DuknApWHjei22B2GDgEByE7wCcdlkoKxWawqjy7+Rn2ujhTMW9JLwQTp7/TVmyIVY8IY9PvWic5J/tGt59RTAIgEFuh9XFNT8+uFr7Vp0+Y32OtPsWyqFl50GCQF8zy5BEzHdpyyDBy6BAQgO8EnHAcOodsiC4sdxtLF39h0pGAeR9FtaYlB+hty1PhKVf0C9PvWiZVUO6IAEAm1tbWNbdu2rS18DX428RQwkKRgnies+vGtoyH90G0p7DB0CAgSW7aKCce6dei2yEJn66igDerib2yqIgUTpL9hss/b4KbN6PetG51qR63k1FMAiAQWAA6FYI997VNTU/OP8BWCQvb9MGzbKoUXHQZJwTxPyPvjyePT30O3pbDD0CEgSJ04bUnBzEK3RRY6q/AbNmjnb2zaUjDJPfvQbWmJQfobctR4fjObeGDft27MS8HcbNXf2PGDsWAB37uMRxnvW1/fZS9/DduuSuFFh0FSMM/TkY9YKY98hC4BQeb2A5KCacZiebi6+BubqkjBBOlvmOxzCZib99DvWzfCtrqodtSyFAwFgATX8KrDICmYZymjgKwuAUEu9ZSkYJqx2El8XfyNzdQZNaRggvQ3lCsjCRh/mNhcnhQMBYBIqKmpeb1Nmzb/Fr5v27ZtXW1t7em6uroT8D22bZXCqw6DpGCeZeS9SVbe0GV0Wwo7DF0CglC/HiJPJpxEt0UGFpuA6eRvTKoiBROUvyE3TUjAdEW/Zx2Zl4JpudoRBYBIYAFf6JVXXvmW9f1exvksKJzCgsBj2LZVCq86DJKCeZaNA3tLd3JQp4AgPGmcJQVzHd0WbBaTgNHN36jPVxEpmKD8DULjPAWDTfqx71lHZm5a1Y5GD2vV39jxg5Fggd4X8BWkX1jw9zl8ZT9+g73+KbJpFcOrDoOkYPLMpT9lA8YbTQ2d35ZqwNApIIgtricpGIv5Q1gjtPU3NlWQggnK3zDJ5ytUbNKPfc86slwpGAoAkcCCvvirr75awwK+/86+PwWvgS4gBIPIplUMrzoMkoLJM3P3sdgyGj4I3ZbmHYYuAUFeCmYtui3YLNX2dPI3NiNT5UvpaM6g/A0nzYUEzCb0e9aVjhRMJN2iv7HjByPBAr3BjP8MZIHfP8Frbdu2/b/ZzxexbasUXnUYJAWTZ+rUWZE0Pms6ui3NOwxdAoLUiTMi6JkzE90WbBaTgNHN39hUQQomKH/DRINLwLCJB/Y960pHCuZK6WpHFAAiAg58MLQt/JnxTzBtqgZedRgkBZNnYus2MSCvXYNuS/MOQ5eAIHPnoVhlHTkE3RZslsq/1cnf2Ezs2GlJwaxCt6UUg/I3pBpwCRg26ce+Z10ZrV/YqhQMBYAE1/CywyApGMHY4kWi8e4/iG5L8w5Dl4Agl/qkqeHdHzY1dH3HeCmYUifwdfI3NlWQggnK344ETOIJ+j3rSkcKZv36Fv2NHT8QFIeXHUZ4/CiSgoHnMGm8eA6X5DqhqltA4EjBNJotBVNq4qWbvzHpSMEMG4huSykG4W/ISRMSMN3Q71dnpo6fsqodlZaCoQCQ4BpedhgkBSMoq0adbgFBPtC+hm4LFltKvdDN36jPWQEpmCD8DTlpPNd74lj0+9WZmVutS8FQAEhwDS87DJKCkbtKhW4Bgaxb7UGylASMjv7GpuxSMEH4G2SXeC7konr0+9WZthRMQ/cOJccRCgAJruFlh0FSMAUzNwnr1OoWEOQP25grBdNSm9PN39iUXQomCH+D7BIvccnaHvb96s5QX1sKJlXS39jxA0FxeNlhkBRMebkbWNQtILDldqKzZ6DbgsVSEjA6+hubsWVLxYrzXjmlYILwN7Q1LgHD2h72/epO2GZvSQqGAkCCa3jZYZAUDAzI5RXyxqBuAUHmziORmD9iMLotWGwp71Y3f2NTdimYIPwN4vZcAubuI/T71Z15KZjDJf2NHT8QFIfXHYbpUjDOgHyotH4TFnULCHJpSwqmS3vp8i2DYnicffL+tvb+xmbqzHkhBTNzGrotxei3v+HwC5S3hDYH5S6x71d3JjZvaVEKhgJAgmt43WGYLgVTSpNNBuoYEIT69xR5MqEEui0o99+zs5hwxXNG+BuTskvB+O1vOPzC739gb/R7NYGtpRNRAEhwDa87DNOlYEK9uogBOZZFt6VYh6FbQBCZPEEE3BevotsSNGGVnadc9O5qjL9Rn3fm06aGDm/wVTAZpWD89nf6wiWxAjp1Evq9msDWDhRSAEhwDa87DJOlYGAVhg/IPTuj21Kqw9AtIIgtWSwmHPsOoNsSNNNXb4oBYsIYY/yNTZmlYPz2d2L3XpEDuXwZ+r2aQEcKpoSkGAWABNfwusMwWQomc/2OGJDHjkS3pRh1DAgS27aLCccaueouB0Fbky26aKEx/sZmZOpkseJ8/hK6LUH7O7ZyhZCA2bUb/V5NYahv95JFBSgAJLiG1x2GyVIwySPHxID8/jx0W4pRx4DAloKJGCgF05omm47+xmZsxXJpgyC//R2ZNkUEv+cuot+rKWyp2hEFgATX8LrDMFkKJr7hQ7EatXEjui3FqGNAkLn7WCSmDx+EbkvQjLSiyaajv7GZ2L1H2m1Qv/3dOLivWI16FEG/V1OYT3HZX9Tf2PEDQXH40WGYKgUD2958QD56At2WYtQxIAA5ClOlYBxNtnuPjfE3NqEKCF9xfk++gxB++lscgJG7FrKOTGzfUVJ7kgJAgmv40WGYKgUD2958QL55D92WYtQ1IAgN6CVWJhri6LYERUeTrcMbfHA2yd+YhP8xvsPB/uewbQnS35l7DVJL4OjK1JkLYsIx/b2i/saOHwiKw48OQ2YxZD8Z6t5BrHwmP0a3pRh1DQgiU8yTgoFtOD4gD+pjnL8xCavMDV3bCzHk1Cfo9gTl79Tpc5YI9nT0+zSJ2YeNop0P6VfU39jxA0Fx+NFhJDZvblHBXEdmI2mxMtC3G7otpahrQBBbuqRknoyuhER8PiBPm2Kcv7EJumx8pf/2A3RbgvK3vRVp4ml7TPKV/k7tmho6vtmUy3z2nL+x4weC4vCjw0idOCNOw86Zid6AgmL68g1x+nniWHRbSlHXgCA/OK1GtyWwe965W+QGrVxhnL+xCZUZeK7v8VPotgTlb+cwwv6D6PdpGhuHDrByfRue8zd2/EBQHH50GFAo3LSTmbYmW2xRPbotpahrQGDi9hScQuUD8p59xvkbmyByzyccmzah2xKUv/NyJNfR79M0Qr9W7LQ/BYAE1/Cjw+AnMyUumeQH4+vWCX2wLVvRbSlFXQMCOAVr2oQjMmWiGJA/umKcv7Epq96nn/4O9ethCRKn0O/TNMbXrimq90kBIME1/OowTNOMitqabCfPoNtSiroGBM/UaDVECsY5+RwqffJZV39jMy92PwLdliD87ZQk697BmPYlE0vtLlEASHANvwYIOLbOA6KzF9AbUBAEeYSWNNlkoM4BQePA3pYUTAzdFr8Jp0+59mHXlrUPdfY36vNP2GL3HdFtCcLfmZv3RcA7ehj6PZrI9JUbRWt+UwBIcA3fkoZXrRTL1jt2ojcgvylOar1lndQqrskmA3UOCMrZEtWFcPqUDwijhhrrb2zCaX8+4YjIsyXql79Tx06KLe95c9Dv0URmoxkx4ejd9Tl/Y8cPBMXh1wABkhx82XrJYvQG5HsDbUGrSSbqHBDElllSMHv1l4KB06d8QJ4721h/YzM8aZx0hyL88jccduGHXjZsQL9HUxnq2UlozMZzz/gbO34gKA6/BggoXs1XKSaNR288fjN15rw4hTpjKrotLVHngABWmvmEY/XzJZN0Y3yTpbP5wQfG+hub+RqtB9Bt8dvf0QXzxb0eOYZ+j6YyPO756loUABJcw68BAk6LyS6M7BVV0aHTOSBQJQj3gs6AfPiosf7GplOjVaIJh1/+Do8dKfKbr99Bv0dTWay6FgWABNfwa4CA5HRIkubL1okn6A3IT8YW1yshkqpzQJB9YG/D90e3xW+WOyDr7G9syjjh8MPfvB+3S1xq3o/LzMTmLc9V16IAkOAafg4QpswcofoHX56/cgPdlpaoc0DwbMkkeQ/ieMFQDzsfqOUBWWd/Y1PGCYcf/s6Gk2Inp18P9PszmakTp5+rrkUBIME1/Bwgyt2qUp1wOosPyNEMui0tUfeAQAUpHrd0ak736drqe3X3Nyb5hKNj8RqtWPTD3+mLV8VK5+QJ6PdnMjN3nq+uRQEgwTX8HCASmzc/t2ytG3OxrBiQe3VGt6U16h4QwOyYa0+ekFeM2y0dTbAyak7r7m9sNg7tLyYc90Potvjl78TuvSLXcfky9PszmcWqa1EASHANPweI/LL1LPQG5BfTV2+JAXn8aHRbWqPuAQFMNLj2JJt4YNviFyupOa27v7EZmTlNTDhOn0e3xS9/x1YsF21q1x70+zOdjYP6CO3Jx1HH39jxA0Fx+DlAOMvWIwajNx6/aA/I0UUL0W1pjboHBJBqwH2xYD66LX4xvnZt0bqgJvobm/E1Vo3WbdvRbfHL35H3Jon85guX0e/PdEamTRa+OHfR8Td2/EBQHH4OEMWWrXVjJQMyNnUPCPI1Woej2+IXIzOni1WnU2eN9zc24dQ/X41d3PpqbBD0w9+h/j1brTlNDIbOauzO3Y6/seMHguLwe4Bwlq0fRdAbkB90BuTT59BtaY26BwRO0fpu72pbtL6SvDPd/Y3N9OXrZedjBkGv/c3bE9Sc1rg9qUQnH3PZUsff2PEDQXH4PUBEpk0RAZK1bK0bZUsEb4kmBAT5FYsEui1eE06bwqlTkLspZ0XdBH9jspIT2UHQa3+bsKKuEqHOOT+RPWWC42/s+IGgOPweIGKrVopl6x070RuQ1xQDcjtOFba4TQgIIlMmijwZ1lli2+I1M3cfi5zaYQPJ35Iwr8mYQ7fFa39D6TeeU/v+PPR7I37Bt+H5hINNcm1/Y8cPBMXh9wCR3LtfLFsvXYLegLwmrPrxAXnoAHRbyqEJAQHIVeh6arGYGKzp/sZmsRqtWPTa31Brmst4bdL3VL1KhG142I6HbXnYnqcAkOAafg8QeSHR8egNyGtC3h+/t1nT0W0phyYEBDrrlsU3bRIDMhuYyd9yMFq/UIjdHziEbovX/gb5LqGreRr93oiC4dHDRcrRjbsUABLcw+8BIhtOaVtKCE7+8gF57Vp0W8qhCQFB8zwZnRidP1cEG0eOk78lIUjA8D5gzWp0W7z2N1Sd4MHGXX0r66jGwupaFAASXMPvAeKZYuLJj9EbkKeNcZE1+z94GN2WcmhCQJBt1Ld2aXjUUDEg37xP/paEqTMXxIRj+nvotnjpb1Fb+62mhg7619ZWiYnNW8SEY906CgAJ7hHEABEeM8JZtsZuQJ7e1/jRIv/nKn7+Tzk0ISDgeTL2hCPxBN0eT++ra3uR/5P6hPwtCUHeiucBD+qDbouX/s4+bBT3NaQf+n0R8wT9Tz7hmDmdAkCCewQxQBQuW2M3IC8Z6tlZBBqxLLot5dCUgCA8dqSYcFy/g26LV4TyT3xAHtib/C0ReWDepbLA3C966e/UmfMi0JgxFf0ZE/N0Dh4O6U8BoOb4Wk1NzYLa2toQ42P2fa9Sb6yrq4syPmDvu8F4nb33tXIvEsQAkdiy1Vq2ViNXrhxmoxmx1dhbDg2wcmhKQBBd+L6YcBw6gm6LV0yd/UgMyNOmkL8lo7M1f6u8rXm/6KW/ndzGtWvQny8xz8Kt+SfZTykA1BUsoGvPgrmj8P13v/vd34Mgj/38vRLvDbdt2/ZPqrlOEAMEFEsXy9bT0BuQV0xfuiZEUiepc7rZlICgME8G2xbP7mn7DnG6edUq8rdkrPRwjl/00t9OfrMEp5uJz9I+nJO9+4gCQF3Bgr19NTU1rxf8PJ1xYrH3sgAw8sorr/xpNdcJYoDIPgyLZevB+uSTNC/LowJNCQhSJ8+ICcfsGei2eMXY4kViQN5/kPwtGSuV5/GLXvpbtfxmkxidO1vI8xw/SQGgrmBB3W0W8P2l/TMLBnuwn9eUeG+E/e4m+3qLcflLL730zXKvE8QAwZetO7/d1NDhjaZcGjdPxis6gsMsEMS2pVyaEhBk7jVUVDFDBYYnjBED8uUb5G/JmDohJhxR5AmHl/5WLb/ZJMY3fCjGno0fUgCoKljAdoHxSSFZ8PYxfGXB3reLBIA9SwWA8H7r22+wv5vG3re/XDugw3j6VHQeftLOk8nevu/7tYIgCFvzvJ9LV9FtKZfg56D8jcknWatmbsd2/Htse7xgqJc1IMez5G/JmL2fL9GHaYdX/s5F7RrH3dCfLfF5wsofn3DMm00BoK6oZAu4EG3atPl99r7Py71OU0DILqvn/7RfXDwf1CV9Rbhfd34/X/74C2xTCEUQGyHyZH6eSWOb4hpf/vjHIt+0bzdsUwhF8NWXXzY1dGrHCd+rjp88fijSDaZNxDaFUAQ/TyZE+tGYYRQA6oq6urp3rEMgX7cPgbCA8I+bv++ll176zbZt2/6O/TN7z0D2d6fKvQ78QwWxQpDYvNnKk1mPPoNyy1zMPgHcBd2WSmjSihBsx/Et05Nn0G1xy8zl6yKnceJY8rekhNU/vsNx/zGaDV75O7l3n5XfvAT9uRKf55PMp/wUMJwG3vLaa9/wJuIgyIavWzIwjYwNLADsbf+Cvf6PjMvg+5dffvkVkH4pyAHcyQLC75Z7Eegw+D+Vz3kLjoClBon56UvXrRPA49BtqYTg56D8jU2nkP3Gjei2uGVy734xIC9ZTP6WlPaEA/IBsWzwyt9wsE21/GbTCALd4KPHb36/rR/BB8EQBDVAFApYYjcetyycIWPbUglNCghSx6w8mbmz0W1xy9jKFWJA3rmL/C0pnQnHpk1oNnjlb5jY8tXzS9fQnyuxOKESCA8A2//TP2DHEASFEdQAkT8J/GZTLq12bUnnBPCuPei2VEKTAoLMnUdiwjF8ELotbhl5b5IYkM9fIn9LStAA5BOO+XPRbPDK386Bo2gG/bkSixOKKogA8LUh2DEEQWEEOUA0jhwiTs7eeYjegNwwMnmCGJAvXkW3pRKaFBBAAXs4BQzMZT5Dt8cNQ33FgaNsOEn+lpRQBYSnhYwaimaDF/7OhlPOCWDsZ0osTSirygPAd36wGjuGICiMIAeI6Lw5Ik/m2En0BuSG0DnyATmSQrelEpoWENiJ+Zm7j9BtqZagw8YH5J6dyd8SE/RNoR4w1AWG3Q4MG7zwd/qjKyJXm01ysZ8psTQzN+5aK4A/uIgdQxAURpADBCTk8zyZDRvQG1C1dAbkXpUPyNg0LSBwFPMVnnA4B44mjiV/S87GQX3ExPBhGOX6Xvg7sXO3yG9esRz9eRJLM5f8mE84Hr/z+hPsGIKgMIIcIFInTos8mTkz0RvbHUWCAAAfE0lEQVRQtUxfrn5AxqZpAYEz4UAu0eWGbkoOmuZvbEKtcz7hOHUW5fpe+BtOmnMNwH370Z8nsWUmd+xoetT+tYHYMQRBYQQ5QOhQosuR5Fiq1glgoGkBgSwlutwQTprzAXnPPvK35IyvX496EtgLfzs1gK+UX3KQiEPwM3b8QFAcQQ4QkIzPFfM7vqlsYj5sjYgTwLvRbammwzApINBBeghWmkUN4Ovkb8mJLT3k1t+53OdNoR4drZKDOfTnSWzd39jxA0FxBD1AgCyHSMx/jN6AqmFkinUC+KMr6LZU02GYFBA8Kz30Cbo9FdvPB+ROYkCOZcnfkhMOG2HucLj1dzYUF/nN/XqgP0tief7Gjh8IiiPoAUL1xPy8JIdaJ4DtDsO0gMCRHrp1H92WSpkNJVwNyCb6G5PP7nAEr3Xq1t/pcxfFCeCpk9CfJbE8f2PHDwTFEfQAEd9k1QRevx69AVXKvCRHJ3Rbqu0wTAsIou/PEzl0R46h21Ip8wPyZPK3InQmHLcfBH5tt/5ObN8h8ptXrUR/jsTy/I0dPxAUR9ADROr0eTGozZiK3oAqJZRGUrEGcGGHYVpAkNi8RUw41q1Dt6Vi2+0BefUq8rcidCYch48Gfm23/o7WLxS2HziE/hyJ5fkbO34gKI6gB4js46jIkxnQG70BVUo4+KGyRpaJAUHq9DllJxzR+gViQD54mPytCBNbtooJx9q1gV/brb/DY0eK/OZrt9GfI7E8f2PHDwTFEfQAAYntDd07WCfNnqA3okoYW1wvBuT9B9FtqbbDMC0gyD6KiAnHoD7otlTK8JjhYjvxxl3ytyJMnbkgJhzT3wv82m78zfvlbu+Kfjn5MfpzJJbnb+z4gaA4MAaI8IQxlrSFWlpT9gw5c/0Oui3VdhimBQR8YOvanqvm51JP0e0p2244wezSbhP9jc1sQ0zkCffvGfi13fhb5Z0ZU0kBIME1MAYIN+K2WPRiQMamqQGBs5KmUOAO5cT4gDy4L/lbIWLucLjxt5ObjbBySaze39jxA0FxYAwQyb37lKumkX3QaA3I/dBtcdNhmBgQxBapt3UP5cT4gDxzOvlbMWJV03Djb6dsooLqDKaSAkCCa2AMEOmrN8VpWtZRYjeicqlDWTFTAwLn8M7yZei2lEsv5JJM9Tc2nXq6e4Pd4XDjb6jPrrI+q4mkAJDgGhgDRC7xhG+lQtIxbJlgN6RyGN/woRiQP/wQ3RY3HYaJAUH60nUx4ZgwBt2WchmdZwmmHz1B/laMid17xIRj2dJAr+vG37CzwdMk7ofQnx+xfH9jxw8ExYE1QMCpTF5R41EEvSGVw8jsGWJAPnkG3RY3HYaJAQHkYoHvIDdLlQlH49D+YkC+10D+VoyOXujEsYFet1p/w6lfPiHv2p7nOmM/P2L5/saOHwiKA2uAiMycJgKqU2fRG1I5hGR8HrA+bES3xU2HYWpAAKcbVZlwwCEjPiB3cTcgm+xvVP/ZFYN6dAp0wlGtv9NXb4mAdexI9GdHrMzf2PEDQXFgDRDxDz4QW6obN6I3pNaYnyG/o/QM2eSAQKUJR/qaNwOyyf7GJtRv5hOOhnhg16zW386hvCWL0Z8bsTJ/Y8cPBMWBNUCkjp8ShyrmzEJvSK3RqwEZmyYHBM6EQ4EcTq8GZJP9jU2QU+ETjtPnArtmtf4GNQawNbF7L/pzI1bmb+z4gaA4sAYISDbmsipD+qM3pNaY3HdADMiLF6Hb4rbDMDUgSJ04LWRVZlUvqxIUvTpFarK/sYkx4ajW3+Hxo1Bka4ju/Y0dPxAUB9YAwYWVO7/d1NDhjaZc6hP0xtQS4TQfnyHv2oNui9sOw9SAwBFWVqAkXL4m6y3yt6K0ZaPc6DgG4W+nBBwI3FMJOKVIASDBNTAHCFUqNITHWTPkqzfRbXHbYZgaEDwz0CXkrUHNJ0ZdvKk4Y7K/sWnXoA4N6BXYNavxNxxqU2ViRHze39jxA0FxYA4QscVWhYa9+9EbUyk6AzJfqVSzBFxhh2FyQOBUaJC4BnXm3mMxIA91nxphur8xCROOUI+OoiRcLBvINavxt5MaobDAvamkAJDgGpgDBNQClv30WebuIzEgDxuIbosXHYbJAYFdgxqEerFtKcXk0ePicNS82eRvxRmeNF5MOD66Esj1qvG3SmoMxOf9jR0/EBQH5gABW7/8dO3o4eiNqRSTh4+KAfn9eei2eNFhmBwQwEqzOMxTj25LKcbXrhFB6pat5G/FGVu1Uvhy2/ZArleNv1WSRyI+72/s+IGgODAHiFz6k6aGjm82NXRq15TLfIreoIoxttLqxLfvQLfFiw7D5IAgP+EYhm5LKUamThID8rmL5G/F6Uwe588N5HrV+BtDr5Donb+x4weC4sAeIBpHDhEHQW7eR29QxQjlnPg2zsWr6LZ40WFg+xuTufSnbMLRjhO+x7anGEN9uooBOZwkfyvOzJ1g00cq9Tf8j/GDKux/DvtZEavzN3b8QFAc2ANEtH6hOAiy/yB6g2pO5+QoJHLH5T05WkmHge1vbIZHDRUTjht30W1pzmyjtwMy+RuXz0pd+X+ArFJ/p86cFwdApk1Bf1bE6vyNHT8QFAf2AAHaejwva9kS9AbVnNkHlkTC4L7otnjVYWD7G5sg5u2FyLIfhDwsPiBPf4/8rQnDY0Z4ounoh79BpJofAPngA/TnRKzO39jxA0FxYA8QMhciTx07qUy5unI7DGx/Y9M5CLJIvoMgzonMDd5UjyB/49Op6rLH/wlHpf6OzJgaeLk6orf+xo4fCIoDe4CAKiCwRQJbJbBlgt2oCumcyNy8Bd0WrzoMbH9jE7Z++aruyCHotjRnZOpkMSCfuUD+1oRBTjgq9XeobzeRbxpKoD8nYnX+xo4fCIpDhgGicfggkZd1+wF6oypkZMpEsX3jwYlMGUgBwRf8tDmcOofT53AKHdsexy4QDu7ZWQzIkRT5WxNmbt4LbMJRib8h6OP5piwIxH5GxOr9jR0/EBSHDANEdOH7YpvkwCH0RmXz2QE5jW6PVx2GDP7Gpl2CMH3tNrotNv0oHUb+xmcu81n+IIjPtXYr8Tds+3qZb0oMnhQAElxDhgEisXOX2CZZvgy9UdnMPgwHXssziA5DBn9j087LkqkiSD7fdCb5WzM6JQgvXff1OpX42+t8U2LwpACQ4BoyDBDpKzekOwiSPGKV5JqrxwEQu8OQwd/YBMkh7tv6hei22IytXuVZBRDyt1x0xOR9rghSib9B+kXkm55Hfz7E6v2NHT8QFIcMAwQ/CGJXBJFEoDe2Yrk2FUAKOwwZ/I3NzK37Ii9rxGB0W2w6guMe1o0lf8tBp76zz5PJSvztpeA4EYcUABJcQ5YBAuoBB6WXVZY9Y0cKey7fQLfFyw5DFn9jMp+X9WYgAr2t2gOCwSA4/u4PPRUcJ3/LQTudpHFAb1+vU66/oewbT2/p1wP92RDd+Rs7fiAoDlkGCMj/4ytuO3ai2yJOir4lToqm5Dkp6kWHIYu/sZkP8P3NyyqHmbtWybCh/cnfGtKPE95u/J06fkocAJk5Hf3ZEN35Gzt+ICgOWQaI5JFj1jbJbHRbMtfviJzEUUPRbfG6w5DF39h08rK2bkO3JXnwsPjff38e+VtTOjl3p/3LuSvX37FV8vzvE935Gzt+ICgOWQYImU7dOuXplspXns5thyGLv7HprILMwl8FiS1bKgbknbvJ35oSTtv6XXatXH+Hx42SZvWb6M7f2PEDQXHIMkDwbZJeXcQ2SSNuYjKsxHBdwoOH0Z+L1x2GLP7GZjZk5UH16cr/9zBtAZFgLoR+/Q75W1Omzl4QE46pk3y7Rjn+hkN2jhC6RuktJpICQIJryDRAOLUpT5xBtaNxSD8xIN97jP5MvO4wZPI3NkP9e4oJx6MImg25xBNRCrFLe344hfytJ7PRjJhw9Ojk24SjHH+nr94U6S1jhqM/E6J7f2PHDwTFIdMAkdi8WWyTrFmDZgNU/eAddfcO6CtDfnQYMvkbm5Bvyld6jxxDsyF9/pIYkCeNI39rzsbBfcXE8q4/E8ty/A2yVjy9ZcVy9OdBdO9v7PiBoDhkGiBAA40PhhPGoNmQOnVW2xJJFBA8Szhxjl2BxskNW7+e/K05nZKXe/f78vnl+BsqzfBdlqMn0J8H0b2/seMHguKQaYCAWpl8O6zz255vh5XL2CqrIsPmLejPw48OQyZ/YxNqAWOf9o5MmSgG5LMXyN+a06lA4/Fp70r8Ddp/PO3hcRT9eRDd+xs7fiAoDtkGCL8S4stleMwI7QSgCzsM2fyNSa73aAtCs8lH4NcvFICOZcnfmjNzP+SrIHRr/oagj6e39O2O/iyI3vgbO34gKA7ZBghHEBqhBBtfgeQl6d6SpiSd1x2GbP7GplOC7cLlwK+duWmVpBs+iPxtALnSQW+rBFtDPHB/Jw8f1a6+ucmkAJDgGrINEI4+24ypgV9bhhxEvzsM2fyNTdBl8ysHrzU6epNLFpO/DWFk9gyRB3j0eOD+ji5aKCbXu/eiPweiN/7Gjh8IikO2AQJKJTmncLM/CvTaTkL+unXoz8GvDkM2f2MTM+iHlRgeDBw6Qv42hM7Bo2VLA/d3/hTyI/TnQPTG39jxA0FxyDhANA4bKDqqm/cCvW5kygTfEvJlIAUEzxPEcIUwbjv2/dPgrsuFzzv7th1I/paTdpnJxhGDA/W3I3zeq4t28lamkgJAgmvIOEDEli0RWxVsthzUNfmBgK7tRUJ+PIf+DPzqMGT0NzZh9S/oPMDM7QciEBjSj/xtEPnBn67viH4mmgnM306t9TmU/6cLKQAkuIaMA0Tq2EmRBzhzWmDXTF+6rr1CPgUExYmRB5jYucvX/D/yt7wEjVG+03D8VGD+ji2uF5PqXXvQ75/onb+x4weC4pBxgMiGU/mySQHlATpBwLq16PfvZ4cho7+xCSt/QecBwuSGBwFsskP+NotOHqDHwX9L/m4cbJW3vEP5f7qQAkCCa8g6QDQOHRBoHmB43CixDfjRFfR797PDkNXfmITcP8gBDCoPECY1cMiJ5/9FUuRvwwhBGN/+H9QnEH/n8/86U/6fRqQAkOAasg4Qjh7glq2+Xwty/pwKJOlP0O/dzw5DVn9j09YDDOIAkHMQwCf9P/K33OQHgPp0ExOARxHf/Z08cIj0/zQkBYAE15B1gEiduSC25SaN8/9adv3f9yah37ffHYas/sZmYvNmsS23Yrn/12KTmiCuRf6Wl1AOjksA7Tvgu78duSEWCGLfN9E7UgBIcA1ZBwi+LdfpLV6ZI5d44uu1nNXGrdvQ79vvDkNWf2PTqcox2L9TuTad1cbT58nfhjJ58LC1KjfbV3/zdIMeHcVqYyiBft9E70gBIME1ZB4gIlMmioHy1Flfr9M4pL+Vb3gf/Z797jBk9jcmn9mWe9jo33ViWV57mKcb+JxvSP6Wl6D9yPPyenb27KBbMX+nr9wQE5uRQ9DvmegtKQAkuIbMAwTUA/ZbKgMGe94R9+4aeOURjA5DZn9jM7rwfatU1h7fruFIHE2bQv42nJADyg+eXb3pm78ddYO1a9Dvl+gtKQAkuIbMAwSULOLB2YBevp1esyUZovUL0e83iA5DZn9j0wnOpr/n2zXs3C8/g0zytxqEkpNeBmfF/A26pjzIvHgV/X6J3pICQIJryDxA8G25/j2t+pWPfblGZPJ4sc188gz6/QbRYcjsb2yK7dk3mhq6tPflNDjPx7LLv3l4+pP8rSbT126L7dmhA3zxN6+r/u4Pmxq6vcsrHWHfL9FbUgBIcA3ZBwi7LFx802bPP5vLv3R8kx82ySU/Rr/XIDoM2f2NTbssnB8HNNJXb4kBf9hA8jdRTAisvNPM/ZDn/oYTxnx3Y/YM9Hslek8KAAmuIfsA4VRpGD3M889OHj0eWD6WDKSAoHXaeafR+gWef7bXW37kb/XplGjbtt1zf0emTRbyL0eOo98n0XtSAEhwDdkHiFzmM14Szo9tswibGfMOcu9+9PsMqsOQ3d/YzD6O5ssQsv89rz4X0hkaB/e1kv5vkb+JnKkz5z0rQ1job7G70a6poVM79r2/MlpEHFIASHANFQYI53Tmjp2efSZoC4IUB0hyZKMZ9HsMqsNQwd/YhNVmHqhduOTZZ0JJQ78PNJG/1WMu9UlTQ9f2PFfPrU5fob+Th4/6fqCJiEsKAAmuocIAkTp9TsySx4707DOdDnKq3tU/mncYKvgbm05VkMX1nn1mfO1asf27ZjX5m/gMo/Pnignu9h2e+TsyY6rY3dh/EP3+iP6QAkCCa6gwQMAJtlDPTp4lSwNhZmxaeSQKCMpj9mGY/280dO/AV2jcfh7f/h3UR/z/3rhL/iY+Q6fs5ejhnvg7F03lD7fFsuj3R/SHFAASXEOVAcIu1xZfv971Z2XDdgfZzqgOkgKC8umUazt6wvVnpS9dt8rM9Q1s+5f8rQ55nrMlD5S51+Da38mdu6wyc7PQ743oHykAJLiGKgNE5vodkUPVv6frih1Q85d3kPO8q8OpAikgKJ+wdebVCfHogvlii2/zFvI3sShjy5aKCe66ta79beewwsoi9n0R/SMFgATXUGWA4NtoQ0XN3tS5i+4+Z0g/K8n/Mvp9Bd1hqOJvbMLJSXFI6I2mbEOs+s8BcWn7sJHLJH/yt750Dgn16tKUS1cn2gx+/lk8mi9t6eEpdqJ8pACQ4BoqDRAJa2vDzcm29KVrYjtuUJ9At+NkIAUElRHKA7pdlUns2iP+Z2dM/f/bOxcgq+o6jg/LRI09zIkVu7Sve3d3MqOmZtKpsTJ7TY6O4wBrkewWUiopUyn0wIIgJ5spaYnIJBzFB5YYzkSJvMIxNUUo0BF2WVjYZZ+AYNODscf2/Z37P9vpdnf3Pjl77v18Zn5z/s97/+f+z+N7/0/qGxvVbJJbPuv2ecu/rHEL569dG/r5YMU1BCDkTZReEF6rzBdbvCUTcp0M4s+O6/7lw6GfTxgPjCjVd9jWt+elZGvKvGtzmgxiQxX8yR89T5757jjqO1p2dNPm5GSQJbfmlN8mf3TMvSbZ2nygK/TzwYprCEDIm6i9IPzJIDZmJtu8fS+0JWd32t6YZTT5I/jAiFp9h22Hli1OtspszH6x8J6tv0u2Nn/95lBam6nvaJntP21dwN7wlOd2Z52/e926shzbXK6GAIS8idoLon/fQW9cls3gtV0bssnrLyh9JtdiG0+GIMje/DUovclHWYzNMsF3aNHCpHjctJn6xjIy65nwhgzc9p2s8tkf2o7rP5+cSbx7b+jngRXfEICQN1F8QRxetTLrhXr79u77r3DsKM/uEQRB9uYJuW99IzlsYMOjGefz95n2hGNfboP6qe/ys4Gjx4Y65s3NuhXQ32e6t/UH1HeZGAIQ8iaKLwhvv1YJORvrYsJurPTeS3zZkrwH9EfdEAS5mc0WT87QnDs0kMG2gTZe0ISf1/q3JbcB/dR3+ZrfCnjwmwsymsnrPQ+/kNxO7nR3F/VdJoYALGEaGxsvk+1saGg4reMdo6VNJBL1SvOUrE3pn5Wdn+n3RPUF0XXvPckB04sWjvmQtFl13gv8puu8PYDDLnuYD4yo1nfYZusBeuOrWpePmdb+ZHjX5uJFoc40p76jaTbUwF/yaqzt4ez68nc1OrJyBfVdRoYALGFM1MXj8WkSc0vHEoCK31ZfXz/b3Eo/Xf7nMv2eqD4wrJXl4IIvj7k7SP/+g96WXvksr1AqhiDI3WwtQJs8NNbuIL3P7PRaYmynmTO57Rv1XVrmL1dl27mNdh35S2NZt/HA4V7qu4wMAVgGSNgtHk0AKr5Sou+UnBV+mNL3yeKZfH6UHxi9z+9Jbuk2wixNG+tn2295LTcrfhR6ecM2BEF+dvSxzcMvZRN6qfH2ovb/bIyHZYao72jbkbvXJMXd/OvTLnvVs22HNwzG/nDYMkPUd3kZArAMyEAAvlfx+4Jh1g2s8Esy+fyoPzCGX8rWBXLnT4f62zq9gdQ29qpj/nXD62oN9BwPvaxhGy+I/M1mkHvX25zPDnU99Iuh/s5ebwam1xJj47Dsz8bKFeNikXHqO9pmQ1v8oQcdN8zxtie0Z5vtKONdh9bSbH82Hl5PfZehIQAjjETa07LBoEnIHXPHqX66XASgdQFnIwCPH09eTFG1nse3JCeFOCEYtM7bvzs02D0QehnHg1k9l0J9h2mDg68MdT/wQNprzfsTsvquocH+k6GXk/ouDRvsOzF0uPWO9NfbnFlDR/XHg/ouT7N6zlmAQDQodhdwqdA+a3q8reXqn7c3N3UfaGk6qeMT7c0zZy0J/C4AhaKteeaF7S1N6w80Nw3oWjsu98b9zU0fCbtcUJrsb55xZXvL1Vt1nZ3QsUfH+/c3T39X2OUCgCJiAlACb/loaST2tstaXPoZ2UwCAQAAAIBxQiKRuFTCr9ta92SvyLpkl1ucRN4Vsrv8tPF4vNG6lG0ZGNf9e0F4JQcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgOxpbGy8TLazoaHhdJo1BifU19f/WHEdsna5vxRKIaFouKWFbPHx3bI/6hq4L+wyQWGxvcRVr0/ZygC2M5Ds/LDLBMVD9XzYNgSw+9nua93jM8MuExQO1Wmr6rdTx3/X1dUNr//IfQ5ZYxdNPB6fpotlaaoAlL9Z4VvMXV1dfY49WLioSouxFheH6KP63aZ6nm1u3b/TWRu0tFH9HrJnetjlgOKgur24qqoqZvUcFIDc55Az6YSALqKNCm8K+L9vQvHMlw6KRSaLi0N0YXeg8sNah4LCAEqTYD1zn0NepBOA8u/VRXVRIM0N8t9zpssGxcMJwG7X/bs1032jIRqk2x/cuoeo59LFdQ/+Scc9stWxWGxy2GWCwpMiALnP4f+xXUHcGK9h04VyzB2n+ukyFIDzEIDRYqz6TyQS5yrZREsr9wcUPqBjVcjFhgKR7sXgdgi6JKQiQZFR3b7NOSeqrm/XPf2bUAsERWEsAch9DhlDFzAYqt9Nug6uCrscUBjoGipvamtrz7PtQ8MuBxQeuoChYKQbC6aLp8VNAqnwJ4Gwt3BpEWwFjsfjDfbQsIlBYZYJCovqdLvdy+bW/TuDweGlSywWO0v38dm+X/X9VT3Dd4RYJCgSqWM9uc8ha/Syv9SNATtl/xRlXbLLXXSFWwbmoOyALqgbQy0sFBzr0ndd/TYGcCetf6WHBEGjDQWw5SFctxB/4kqUmpqaOrekkz8GcIPqvzrsckHhUN3eae9s1e2r9ofdlmizcO5zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgOjiFoB/JpO0bgH5dbl8j/J+2NYxyyUvAAAAABQQJwCfziStE4AP5vI9TgD25pIXAAAAAAoIAhAAAAAgSySIbrEtFSVu/qxjh4ROUyBuoW2tqLhjOv6qpqbmrX6c7e3p8u6S+y86rq+trX2z8t9r2zTa1l5yv8NPX1dXN0VhDymuX3bExNhIZVK6R5XmZ4FyLJc9PkLa/xGA8v/QPt/OR/a83B/y45wAfETh97nzfSEYP3ny5DcGtq7qta0lFTzJ5UUAAgAAQPRx+3H+NZFI1JvfRJpE3NvNrfDPSfAcUpoGiZ/Xyr9K/if9vCYAbT9mpT+vurr6HLen536l+7iiJ+jYGhBt5n9WtlTu11geE4763GvTlWvq1KlvUfxRxV+pz/yYiUYrW7q0qQJQ7s9YeeSskHu+bEDf9zqLMwFoe5IqbJbFy90s90md49ku7yOyNVOmTHm90r5J8Y/Jv8zlRQACAABA9JGgiZsA1PEqXyT5KHyL7CbfX1lZ+QYTTzU1NXUurwnA5kD6Vvl/6/slmN6vsEGX9kJZT/DzFX+NwraNVDYTkpbfWuOU9opRzmHULmDFv6z873HfaQJwZ8r37DZBqLhKOz8Tf4G8H7QWUJcXAQgAAAClgYTNDImcHdZtK/u1tQpauNwvpQovmwWr+Iudu1PxnwjEfU957g743y3/39x3zJT/HybGzKzVTXZK7r2jFK3CtSruG638abqAb7ayu+8w+6drlRzuAk7Jv0FhC3Re79PxX34ZXTlP2e/i8iIAAQAAoLSwFkDXbfuE+UdqAVS6WvNnIwB1vMi6k7Mpjz7727a8i7XQyf2VkdIFBaC12MmOK/0FgfiX/XKO0AK4y1oArYtZx9MKmjhCeRCAAAAAEH2stU/2URvjJ+9EHW+TyNlucTYG0Lo/bQygiUOF/0T2ez9vhgLw785b4cYA3hqLxc6Sf4KNOwxOwAjiBOMJ6262iSTWkqf070yXNigAleZT1krpJqtMUvgia3lMEYCvyj7tzne2fbZNXnHfa2MAV/l+fV6V0nzS5UUAAgAAQPSRuJsmwfMHN2vXuj23+l3AYoJEz9es5c5a1WxmblVVVczPa+GZtgAaElPn2gxhGwvoumZ3BWcc+9gYPMUdMGHnh1lLpOsunpSaPqUL2LqNV7vzse+5JVhO1wW8XmFr3SzgF03Y+Z9lrZxuLONh1/37otw3urwIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAcPgPiiXScSbN+WcAAAAASUVORK5CYII=\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"with replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=False) as figure:\n",
|
|
" figure.plot(np.sin, label=\"sin\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"scrolled": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"with replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=True) as figure:\n",
|
|
" figure.plot(np.sin)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"replot.plot([np.sin],\n",
|
|
" xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=\"best\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"replot.plot([range(10), (np.sin, (-5, 5)), np.cos, (lambda x: np.sin(x) + 4, (-10, 10), {\"linewidth\": 10}), (lambda x: np.sin(x) - 4, {\"linewidth\": 10}), ([-i for i in range(5)], {\"linewidth\": 10})],\n",
|
|
" xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=\"best\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 17,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAG4CAYAAADVDFZ+AAAgAElEQVR4nOx9CZhVVXautpmHl+G16cR0twhV1a2dztRJJ3nvJemXoZN+SY9aVYrULSZBZlHAAREUERAQkVEQFFRklEEUBZkHARlkpu48D4hjekrbbb29LnW1KOrWPeee85919jnr/77/q6pLUWfvvfZe6z/n7L3WFVcIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgENqOuru6/amtr/6HC78Rqamr6WrmOusZMxYL6Wx+qv/UVK3+rEtTf/0d1rY/Vt5+x8++qv/mvqv3n1NcP1NfJ6mtP9fWsndcQCAQCgUAg6BJKgPQhoaMEzyOVflcJlWb1u6mufqeccLIqANX//Vv1d3/arVu3P6z2b5SD+rtPq/Yt63A96scvrrBZAJL4U3/7Tjv/pkAgEAgEAoEpKEFySAmd84p59eMvd/W76nd6Kya7+h0lbr7RJpyu6nAdqwKwV6VrG0Cn/XNYAH7Uo0ePf7LzbxpAl3YVCAQCgUDgI3Tv3v2vSOQosfNNerpGryO7+N3/o/79J4o/p1e+9BpWfX8L/Rs98SNRo/gF9f2P6W+Wfkf97XvodzoKwG7dun1Z/d5LJDzpqaL697nXXHPNb3R2bfVvE9pfW3092dam31F/cyH9/zYR+7L6rK70/9S/jVe/v0d9/pD6mlFfT3Xyt+9V/Jnif7dr8+dLAlDxRvVZC72yVdxy7bXX/lG7v/+r9ORUfR5Wv/OO+rpT8c/LjF9tW9vpb/6YrqPG6393fKp69dVX/5b6+Rn1+QUSvIrD28Yn0HbNy56wdvwbbYJ2pfo6rzQu9PkXvvCFa9T3zyum28b9eTXmny1nc4FAIBAI/IwrD9fX/w6RvudujJ0goaB4pO37F5Ro2NvV77cJjcuewpUEIH3f7snZlR3+7ycC8I//+I//Z5swGa5+/KXPf/7zv0/iSvFJM9cmAak+36b+7tVKUP5a2x7BZElItgnAn6nPxqoff4V+p9w4lHkC+LH6/FkSZZ/97Gd/m8aHfrfd/3umnSj8jPo/g2mPIgnTcv1oG6v/W65f6vslX66re3Pg3/xNLbVX/fuiNnHaXgBe8mSyk7/xdNv/aVY/XtXW71+hvYbq36bSzzRG6m8tpfaXa6vA+zhdX/8rh7/2NXpC7CnfJhAIBKZBDjHYq+HGlubGp0KBhv2hQOO7oebGVmIw0PBf6rOT6uuLwaaG29tEoZZQIuB3VfD/kRIFA+hnEiUkLJR4+Wq5/2NSAJbdA6i+juwoNulpGD2FvKJMIOp4bdoL2HbdP2n3a7+kfu9t9fcb2q4zvtKexbb2l30FrD7/43afkcA7Td+3iVi6fk2HvxXs6klq+7Ei/PmXv3zbV7/85XfUPFvREqg/9pUvfal1xXe/1XpxzjW8f7TnjYfr1P8Z9L++Pm/HN77xayYE4L4O4/f9jmNBfaP20JPBSmMk8AZCt/7g8y1NDbcpH7ZcMV3ybcqvfazm248UT6i5OCPUVP+Par79End7BQKBAI5j3/ve7wab6scGmxsznzjFimz4kXKii88Gvl9X+QruAh1EoFeS9HSr7aMr28TL/HL/xy4BSK8m255QvVui+ux9EqTtX7F2dW0lVP+artPxtbH6vcPq81FtbRlf6almW3sM7QFs3wb1/dfbnhC278N76usP1dcxXVyrOFYnb/7uF4LNDbPmfOuff/y//+Qrxfn0Zs8ftH6prq51W/13L5lnf3XDDa0L/t+/qBuQxrfn/Ps/P2dEACo+1+G6Y2j/Ycf20pjTAZtKYyTQG+d61X9JzaVVir8w7t8a8+pGd0zoW9/6Ve72CwQCAQT0xE8F4/MmHOMlVCLwo5ZAw4S2VylagPa1tYmwrGKO2PZE8MN2ovASKKHQVEkAqv//9waeAD6gfn7dZHs7ewLY8YnlVfRqWf39+rbr0BPA3ZX+tvqdxWYFoLruF2sv7p/8vJl+0FhN+5d/nBsKNPyY5s78b/1La0kAqnnUSk8AX/jOtz6ZW8dvvan1y0oUkgCknzff+O2iSNzT+N3BV7Q9LVXtuq+TJ4CX9IdeIavPQ2baKtAfp+vrfysUaJyt5tvPq/dvjWElIP+duy8CgUBgG+jOVjnGhdU6xsscZXPDIXrFwt2vSmg79EGHEf5BCbc/aMcaeiqo/n1IZ/9P/f6/0gEG2rPX4fNPBCAddmgTRje0/532ApAOi9ChCXqlqv7Wr5c+Uz9/t1yby+0BpD1s1Hb6O+p3ZtBrzs997nO/2dZPQwJQ/d6ktlemn2n3mZFXrWsVN5AYpJ9pn6Bqy79fd911n+vsOmcD3/+fJN7WfO//fTJn2gtA4pD//bet3/nLv2g9eMsPWk/2qm8d8fd/13qDEoUlAXii102tf3H99a1T/vUbrecC9av/+atf/Tsa20oCkES9+iyu/u0h1bf/0Tbmf1B6XS7wHk73qq9RPum0bf4t0DBlgs2n4gUCgcBxHG/65m8q8bfdLufYzkmmW2658cvc/esKSgS8qPhqmX+jgxSXnZZtw1Vth0UutL1GvLnt//yi/b622k8TNr9beh2qvo+2PwVMp3WpHfQEsu1V5Km2wxqdojMBSPsY204Bp2nvn+IrSnx9qfTvRgWg+j/XkgAsvRptfwr4ii4EYNsp4AfanRKm07VrOstVSK981fwIfrmCACSBN0iJwK/dcH3r/1Kfz/jmP7V+/Ss3tC75j29+8jvLvv1vrd/406+2/tn1X279wdf+8v2vXf+lhyoJQAK9Xm87uJJoe+UeVO2fXWl8BPqhJVD/9fb7l230b6tpnzR3/wQCgaAq0GZ65ch22u0c2zEfav5eD+5+CtwBFTD/MNjcGKlmLh279cbiK+CXfvCfXT15PqbzgSSBvQgFbvwLNSc+RPm3YKBx7ar6+qsqt0QgAELdwc5qe/3xsbqL/9Nyv6fucvu1bXAP1V5MNSGT17+4kk5cAsXfRQYaQirw/37l5gi8jMPf/vZvhJobjhidN/tv/n7ruu//R2tLoKH1SM8bW/v/3ddb/+nPvlr8ucug3Nz4upzaFNAWlIs3oGj/1ihPjgW8oOS0lMKAXi+VE4DdFCgJLOUKo59pz476fpCzLRW4BS1NDXfBneMnd8oNlIBX8mv5GGoOLDEzZ3Y3fq/13/78T1v//Povt/7VDde39vz6X7XubPiuwfnW+Ch3fwV8oENoag4ccMq/qZvcXtx9FgiKG8zLCUBKCUFpJ0o/9+jR41tG9gUJvIeLr0Yaf+aYg6Sg3NQwnLvfAh609Gr4npNzjdhy603/zN1vAQ+Ur5noqG8LNPxXsOeN3bn7LfA5KgjAJ2pqau5u9/P1dBrOscYJXAF6PaYc1ltOB2RK93Guqf467v4LnEXLLd/+rLJ9wen5pm5wYnTAibv/AmdxpqnxTygdlfPzrYEqychbDgEfzAhASk8hAtB/CAUaBzsu/j51kmu4+y9wFsVKMkzzjXJScvdf4BwmXHHFZ5R/28c130K9Gm/lHgOBj4F6Bfzxxx+3CvTHz3/4w9bIkP48zrGNPz57mnsYBA7hp8lEa6j3zWxzLXxbU+tH71zgHgaBQ/hw325W3xa7c0jrxz/7GfcwXAa79IXA5ehKAF577bXXUX4uSnp6xcVyV3QIZLCRv0uT6MKFD1vffluoM5NLFrM6SGL03lGt5wvvs4+F8CJpXaPWd2zqI+zzLf7ETPYxdhOR9ubk+fy7rZE7h7LPt/S69exj0dHetooMgfugxNwCyvyvBODP2kpZBelz9f0i9f1/ln6vLQ1MmNLAUOLYKwymgSGHUVxk54W6Mh9Nt4b69WJ3kMTMzj3s4yG8SFrXiPWdPXSUfZ4V2fvm1tyZMPs4u4Uoe3Mz/fJm/rmmGB46oLWQfpt9PNrbGyQ7BH6BFx2G35h89ll251hidPxY9vEQXiRKEMQmP8w+z0pMLJjPPs5uoRcFYCH3niue/pWYWrOWfUza25tbPwg0h9ccht9Id6ThQf3YHWN7Zg8eZR8XIUYQ5E4F2efXJezXq/gEnHus3UAvCsD0lm38c6wdwyOHtBby77OPS8ne3PpBoDm85jD8xtS69exOsSNjj05mHxchRhAknlzAPr86kp6Ac4+1G+hFARidcD/7/OrIzI7d7ONSsje3fhBoDq85DD+xUPigNTL6DnaHeBl739yaDyXYx8fvtFsQFBL51tBtAf751YHFvVm5d9nHm5teE4C542fY51ZnjE6cwD42JXtz6weB5vCSw/AbXbMZvxMmly9nHx+/025BkHpxHfu8KsfMdnc8lfGSvblJ+zu551U55k62sI+PCECBZXjJYfiN8TlPsDvCcgzfMdg1e2X8SrsFQXTsGPZ5VY6UloZ7vLnpJQFIe5tDA9z3tLnE5DPPsI+RCECBZXjFYfiNheR5V76Oa8/M3gPs4+Rn2ikIcifOss+nLlncdpBkH3Ov2Jub6de28s+pLhgefjv7Da4IQIFleMVh+I1uyY3VFeOzZrKPk59ppyBILFnCPp8qMbVqNfuYe8Xe3HRTqqFyzO47yG5vbv0g0BxecRh+Y2zyRHYHWJEDmlsLmXfYx8qvtEsQ0JOO8LCB/POpAukVNfeYe8He3MxHM62hPrewz6dK5L7BFQEosAwvOAy/MR/PKQfZk90BGqFszuejXYIge/AI+zwySj9XBvGKAEyt28A+jwxxQID1BlcEoMAyvOAw/Mb0plf4nZ9BxmfOYB8vv9IuQZBY/BT7PDLK5IqV7OOuu725GX1wHPs8MsrMrr2s9ubWDwLN4QWH4TfGJj3E7vgM87aAq+pn+ol2CALKNUnVD9jnkUFG7hvNPu4625ub+Vi2eKCHex4ZJWVi4LQ3t34QaA7dHYbfWEzGq8nr3xIzO/ewj5sfaYcgyB07xT5/zDJ/Lso+9rram5vpV15lnz9mSGU4qV4xl7259YNAc+juMPzG9FZ31cY0wvi8Oezj5kfaIQiozBr3/DFL2kPGPfa62pubselT2eePWWb3H2KzN7d+EGgO3R2G3xh/4nF2h2eW4WED2HNm+ZF2CILI3Xeyzx+zpBPy3GOvq705SQcq3J7btDMmFi1ksze3fhBoDp0dht9YTMcxuD+7w6uG2SMn2MfPb7QqCPLnIuzzpir26+XLfae6C8DM7n38c6cKRkaPYLM3t34QaA6dHYbfmD18HOfI+vZsjdw1DPb3k889xz5+fqNVQZDasBE2H6iSQmhgb9jf9+O+U90FYGL+XJxIu280znc28+w7FQEosAydHYbfiNyPRZn3U6vXwP5+9P672cfPb7QqCGLTpsDmQ2LxYuh2hsT8eezjr5u9OVk8bT5iEGw+UGk5ZC3r1IaXWOzNrR8EmkNXh+FHIh0YlZbLB+Owv0+pHQrxHPsY+olWBEEh9y70CV320NHWzC7cKz8SEyQquG2gi725mTsdwvmePj2L2ROSL7wAu0bs0cks9ubWDwLNoavD8Bvz0TRUnOVjmeJ1kK9KMtt2so+jn2hFEGQPHsWJs6EXDwUVN/33b4JdJ3fiLLsNdLE3N1PrcdsNohMnFK+RO9WC86FU9jL7ruP25tYPAs2hq8PwG9NbcOlfog/c98l1kK+ZEwvms4+jn2hFEEDnQbvXs7Gpj8Cuk1q3nt0Gutibm7FpuPQvqRfXfXKdyKgRsOtk33jTcXtz6weB5tDVYfiNiXm4DdL0aqR0HTqti7oOHTLhHkc/0YogiI67FzYPMnv2f3Kd9MZNsOvQHkZuG+hib07S0+DQ7X1g8yDfEvvkWomnFuH86DPPOG5vbv0g0Bw6Ogw/EnlCl6o9lK5TTDUzbIAjzliIZbWCgPZqwspxUYqWzDufXAu57zSsRIWf8k/qKgCR2Q0i99x1ybXo5gN1Lbppctre3PpBoDl0dBh+IzRIDh942WZ5qm+Jul560yvs4+kXVisIMtt3w+xPdaw7Xo+CNOp67W9uvE5dBSDycEbHp3LQfad02CR13lF7c+sHgebQ0WH4jcj6mJ2VaaOUCbDrzZzOPp5+YbWCAPmaLLVm7WXXSy5dirve6jXsdnC7vbkZfegBmP2z+w9edj2qFIO6XmbPG47am1s/CDSHjg7Db4zPnoVzWK/vuOx6yBPH4WGXP3EUYlitIECmG+rsZG72wGHY9Si/Jbcd3G5vThay7xS3BUDs37/pku0GJdKhENR8o5sZJ+3NrR8EmkM3h+E3QhOkFtO/ZDu9LvK1XP5shH1c/cBqBEEhWYDt/ysn/il9Buy13IBAMachty3cam9uUj5IlJ+JTXqw02vmTgdh12yfUcEJe3PrB4Hm0M1h+I0kllDOKnLvqLLXpUoNqOvSK23ucfUDqxEEmd24TfL0JLvcdSlYo66bPfwWuy3cam9uplaugtk9tWp1p9eE3lT37elYHWoRgALL0M1h+I3pza/BHGRi8VNlrwsVAnMv33cotJ/VCILk0mdgdqe9peWum1q5EicEfLIPUEcBGJsyCWb3rg4AxWfNhF03u/eAY/bm1g8CzaGbw/AbKWkuylFldu4pe126i6W7WcR1KRkr97j6gdUIguj4sbD5lg8lyl4XmQqEkgxz28Kt9uZkMeUUKP9feHD/LlMAUTYC1HxLLlvmmL259YNAc+jkMPzIyN13YhxVn1uK+726unZ0AlAMRNPsY+t1mhUEhcwFnOi/c2jX1869B6s9XCw954ODR7oJQDoQhPIvsRmPdn3tM2HYtelUs1P25tYPAs2hk8PwG6mAOWpDfvT+eypeH/k6UOoC42lWEFApK5S9Kbdkpesjy8L54eCRbgIQWf+3ffm3zljcBzh8IOb6twWKNzRO2JtbPwg0h04Ow29EZq1PPvN05evv3ge7PuWa4x5fr9OsIEDuw0u/vLny9desxV1/82vs9nCbvbkZnzkDZm8jCcDjjz/Gen077M2tHwSaQyeH4Tcmn30W5qC62v9XIvYJ5N3s4+t1mhUEsUcnw+abkSdwyH2Aiflz2e3hNntzE3YSd0CzoRKA6Zdwdajp6aYT9ubWDwLNoZPD8BujEyfgAnI8Z6gNsHyAlC6hkyStQvtoRhAUX4mBakB3Vm6w0zbkcPkAaS8ttz3cZG9u5sMpmG/rrNxgZ8ydDsHaQKeMnbA3t34QaA5dHIbfWNwUf1sAEwxH32G4HYmFC2BOMvvmMfZx9jLNCAJkvWl61We0zdEHx2Ha0fvm4hNtbpu4xd7czOzA1Zum2sJG2lC86RncH+Nj7xrmiL259YNAc+jiMPxG2kOCcpCJubMNtyO9dRusHam1L7KPs5dpRhBktm7H2dnE6zBkXWAn67S63d7cTC7D2ZkOMxltB/TgUTQDtze3fhBoDl0cht+I3J9iZEN+iflQEtYOM0+GhOZpRhAgK7+Y2RCf2bUX1g6jT4Z0pU4CMPYwqPJLcWvJBcPtSK7AHXyip5xoe3PrB4Hm0MVh+I3xeXNgjil/JmiqLeGRQyDtiIzsOjec0BrNCAJYAuj+TaZSYtDeVNS8p0Mu3DZxi705SQc0UDkfo+Mqp7dqT2Tqo+Qzz8Dtza0fBJpDB4fhR1KdXojoGtpf/X1zSXHjM6fDnGQ+hn1N4mcaFQTFwxf9emEC8oT7zc/9MXdA2hIeNpDdJm6wNzdzp4Iwf5JYtNBUW4oVj/rcgpn7EyfA7c2tHwSaQweH4TcWKzKAnFL28UdN25v26qEcdmbXPvbx9iqNCoLc0ZO4gLxksel2U61oVHtoSwO3XbjtzU1kffOu6k2XY+S+0Zj23N4HWoFGBKDAMnRwGH5j9tAxmIN856V1pu2NbA/lOuQeb6/SqCBIrd8As2/m9R2m253e9DKuPdux+7J0sDc3E0/iMgtQiTfT7QFmOqimPWbsza0fBJpDB4fhN1IZI5RD+tGpE6btffGJJKZGrNGcXULzNCoI4k88DptvlF7GbLtzb52GtSe5bBm7XbjtzU1KAo+wbXhQ36qeuNFTQ9R8S2/ZBrU3t34QaA4dHIbfSElEUQ7p5z/8YVX2jo4dA3La/aCvSfxMo4IgMnoExrbDq9tzV8yBCUoI7eUbDh0EYCH7TvGkLsS2j0ysqk1UpQblbxNLlkDtza0fBJrD7Q7Dj0QFZEpOWq29Ewvmw5xkviXGPuZepBFBUEidh5X7i02bWnXbow/cB2lTtU+JdKAOAhBZ7q/a7STFhNBqXiDaFH3oAai9ufWDQHO43WH4jYVkARaQ44/PqDpApF95Fea4M9t3sY+7F2lEEGQPHoXZNbVyVdVtp9OcqHYZqUusI3UQgKl1wP2mu/ZW3S5YXsKBvQ3VJa7W3tz6QaA53O4w/EZkXqrU2rVVB4jcqRZYu+QgCIZGBEFq3XqYXbMHDlfd9vSrW2DtQu7Lcru9uRmf8wTMrlYqbySXPgNrF9UcRtmbWz8INIfbHYbfmFq1GueIDh2pOkAgk7fGpjzMPu5epBFBAAvIVHs3/XbVbc+dBuaKW2w+NY0O1EEAolKuULJ6K+2i0+qo+VZNahqj9ubWDwLN4XaH4TfGH5sGC8jnVUC2Ym/azwJx3h5P0MtFI4Igcs9dEJtGxoy01HZotYgHx7HbhsvenCxk34UdAIk/Nt1S22gfMkoAom44RAAKLMPNDsOPpIMakIB8952WA0Ri8VMwJ5kPp9jH3musZO/iiUxQeh86yW61/VRJATLfaF+WBw+CuF0AUk1olP9IrV5jqW3FgyCD+0HahrrhEAEosAw3Owy/sZDEncikV31WAwRyX1Zmt1QEsZuV7I2sAELVY6y2P/nM07D25c9F2e3jtL25mX55M8yetHfaavsoRRCkfQOaIQdBRAAKLMPNDsNvzB4Cnshcv9FygMidBB4EeeEF9vH3GivZO/3SJlcHZOS+LC+ePHe7AERW3Cgk8pbbl1y2FNY+qn+MsDe3fhBoDjc7DL8RWZIre+SE5QBR3JeFStBrIWecsHNWsndi/jxXB2Tkvqzkc8+x28dpe3MzOn4sxJaRkUNtaV9m207YfEtvtf/kuQhAgWW42WH4jfF5czAOqE/P1kLmHVsCBCxB7x2D2cffa6xk7+j992AC8l3DbGn/xQS9mH1ZsUcns9vHaXtzsnjzOCCAseV0e24eqWwhSgAmly6F2JtbPwg0h1sdhh+JqpFJB0BKDsOqvZGF3PPxHLsNvMSu7F0st9avF8SOdJLdtjUBOgjixRsONwtAZFofu7aPFG84hvSHtBGR6koEoMAy3Oow/EZoQG47kWlHgEhvegXmyLN7D7DbwUvsyt65E2dhdkytXGlbHyiFBqqddrymdhPdLAAp+TbKjpld9h0gi02eCGljePjtEHtz6weB5nCrw/AbkQcsSikS7AgQbk7lILyUXdk7vRl4onvPG7b1AdlOOw6quIluFoDQE93hpH3tBFYEsfsNhwhAgWW41WH4jZQtHhbo9h/8xGFYtffFZK63QtoZf+Jxdjt4iV3ZO7FkCS7QWSjJ1ZHQJ5U2pKpxE90sAGOTMLV2w0Nus7WdyCeV2f2HbLc3t34QaA63Ogy/MfE0MCDHsp84DDvsHR07BtJOKhPFbQcvsSt7xx4BveoaMcjWPhRy6oajH+iGY/Ysdhs5ZW9uwvbWqXlsZzuRNc9Ta9babm9u/SDQHG51GH4j7A65XUC2K0DATiurQE97Iblt4RV2ZW8qvwcJyIDTtbAbjntHsdvIKXtzMh9Jw0QVvbK1s63IVFd2v+EQASiwDDc6DL/xYhki0B3y1EcucRh22BuZr5D2QnLbwyssZ296IgwLyID8evG5szHt7duzuKWB205oe3Mzu+8gbL5ltm63vb2wbAw233CIABRYhhsdht9Im5hhAfnZZy9xGHbYO3vgMKy9tAeH2x5eYTl70+EHWEB+fYft/Ui9uA7WXjrUxG0ntL25SXstYfY7E7a9vfG5oDccfW8tbmmw097c+kGgOdzoMPzGzJ79uIC8beclDsMOe1P6DFR7EQlT/cpy9oYKqtMh2/sBveHY/Bq7ndD25ibVIYfYD1RjF7o+jp+x1d7c+kGgOdzoMPxGSn8Cczjt7pDtDBC0txDR3vavrIXWWM7esD2c/ZsgARl5w0GHr7jthLY3N1GvVKkqEaK92BuOLbbam1s/CDSHGx2G30inESEOp8Mdsp0BIjZlEqTNXqzQwMVy9o6Ow5SAo0CP6gvVe0W0OTbZ/goNbrM3J5GHKhLz5mLajLzhWLLYVntz6weB5nCbw/AjUaccoxPGXuYw7LI3vapFOUmvVWjgYmf2Lgbk2zA1WelVH6ovsWlTIW22O22N2+zNTXoDgfIT9KoW1W66EUW0mbI92Glvbv0g0AtXngs0/N9goGGc4vJgoPFoauK41vjjM4oBPfvmMXaH4TdC75AXzL/MYdgVINJbXoc59uzBI+x28QI7szc0IAMTK9PpYlS7C8kCu61Q9uZmZvsunJ8AVnKhrSiINoeHD7TV3tyCQqABJlxxxWdaejV8L9jccKjSBI3ef08xuFNqEm7n4QdCA/L6jZc5DLsCRO7kOcfaLayOndkbGpDbKs4gSKeLYe0+5I0bXzcKwOTzy2F2KyW4h7T72Wdh7bbrDYcIQEFF7K+v//VQc8M6s5M0PnNGayFzgd2BeJ2Z7btxge3A4cschl0BghI2o0rCJebPY7eLF9iZvaEB2cYScB2ZOxWEtTv90iZ2W6Hszc34Y9MgNgsPG7CWQWwAACAASURBVABtN/aG46ht9ubWFwIX43R9/e8r8be32olKm8Xz0TS7E/Eyky+8gAvIHYqP2x0gqHQbot2o031+Y2f2js14FBOQba7J2pHFGw5QSbjEooXstkLZm5uR0XdAbBZ72L69dJ2R0hmh/HJ6oz03HCIABWUx4YorPhMMNOyyvNAemSivg4GMz5yOCcjDLt9rYneAoNJGECc5sLfMORvYmb0jo0ZoGZCLbb93FKTt0Ynj2W2FsjcnC9l3WkN9boHYLLH4KWzbaW92v16Yttt0wyECUFAWwebGPnZN2PSmV9idiVcZuftOTEDu5LSZ3QECmb8wH0qw20Z3drQ3bekI9b5Zy4BMjM+aCWl7eEh/dlsh7M1NqrKC8g/plzfD24+74Zhgm725dYbAhaBXv8FAwwXbJi09kZHUHLaTygJRPVKnArLdASKz9wDMwWf2vMFuH93Z0d65oydxAfmVV+H9Sa1cCWu/F7a6uE0AUpUVlL1oLqPbj7vhsGe7hAhAQaew8+nfJw7+ta3sDsVrRJ6k7ewO2e4AkY+kYe1HphTxCzvam0SazgE5s2svrP3Z/YfY7WW3vblJVVYg9up9c2sh/Ta8/ckVwBsOG04wiwAUdIpgc8MLdk9YOs3F7VC8xvTWbbiAduR4pw7DzgBB+/TCg/pB2k8F2bntozs72hsakB3IGJBvicHWCzKpMJe9uRmbPBFiq8hdwxxpf2bnHpx/7pChoVp7c2sNgcsw4eLhD/te/5Y4IACp8+lnQnNNdXKHjAgQ0Qn3Q9ovJ4Gts6O9UcltI6NHONIfuuEgP4ToA6qsGKe9uQmrFz5tqiPtz5+LwPxzav0GW+zNrTcELsOOb3zjl1CTNn82wu5UvMTYtCmYgDxyaFmHYXeAoJx9kPl2ex85CWyRHe0duRNTTzc+41HH+hQddy+kD1644XCTAKTqKqg4RFVhHOmDg1WaqrU3t94QuA9XohYePRLndixeIr3KQNiJnvSUcxh2Bwh6dYaab/lQkt1GOrO9vZEngJ0KyETaGgCZbx5IPeQmAZg9fBzmFyhJs1P9iN5/N6QP0QfH2WJvbrEhcCGCgYaPEJM2tWo1u2PxCqEBeenSsg7D7gBB5b9Qjj679wC7nXRme3vn3jqNC8hbtzvWJzochOpHPhhnt5ld9uZuC/TA0amgY/2Iz54F6QPtnbZ6wyECUNApgs2NGcSkpcXA7Vi8QmhKjjInthEBIh9OwfohJ4Gtsb29aU7AAvKJs471KbsPd8OR2b2P3WZ22Zu7LbADR/1udXQvOj30QM03yqJg1d7cWkMARo8ePWrq6ur2KbbU1tYeVLy+4+/U1NT8o/r8x4pHFY9t+P5/fIiYsFQajtuxeIXpV7fgAvLxM2Udht0BongS+PY+kH54YWM+J9vbG3bgqM8txYoPTvUJmnpozVp2m9llb+62wA4c3XOXo/3I7N4Pm2/09sSqvTk0icBBKOG3TQm8Jvpeibsb1c+HOv5OmwA8Wvo5GGh4AjJpBzRrv0/GLUwuWwoKyD1VQH63rMNABIjohLGQvkTHj2W3k85sb+/Y9KmYgDzKmRPAJRZvOAaDUg/N0zv1kJsEIOzA0WPTHe0HbQuA+Olm66mHRAB6HErYXa2E3fvq28+UPlMCMKfYvcPvkQA8Vvo51Fw/CDVppUSXPaRUBpCAPOaOLh0GIkDQkzpEX8JyEtgS29ub5gXCRrFHJzver+hDD0D6Qjcy3Dazy96c7YDub37+eWf7QqmHBvaG9MXqGw4RgB6HEnZ/qcTe2faf0Wtg9fk3OvweCcAP1O8epn8f/Y9/9xhiwhIzsjHfFsICchcpOVABAnoSOCwngatlyd7n8+8WnwxDAnKZA0dIUgoNRF9oYz63zeywN7cA9MqBoxIpRRCiL5RD1aq9HRUkAmfRmQCkV8AdBeDVV1/9W5/97Gd/u+3f//hvbrjhNGoBplWwp4knrJ7n8+/BagDTXq9y171w4WKAoK929ie7D1cTmPbJcNtLV5bsXTjdggvIr25xvF/pdeth/SnEMux2s2pvu9e3WWa2vA6zT/7kWcf7k5iHST0UHtzfsr0dlCMCp2H0FXBH1NXU3HOi100/gTjIpxe1Cqzhv7MZmIP8cP8ex/vz0bvvwPrz3pbNjvfHa/ivN3EnZ38Sizrenx+dOgHrz4/PnXG8P17DhbWgGrp9bmn9+KOPHO/Pe6++DJtvP/+vDy21DS5CBLxQYm+7YjN9rwThTZ0dAunWrdsfqi9X0vf0JFD9zt43bv5eC2LCUgJL7jtd3ZndsRvmUHJvneryjpFg9xOC8+eBJ4Hnz2W3l64s2Tv1wnLMfOt9c+v5zNuO96sQTsDWT3rjS+x2s2pv7ieAVBkGYRs6cMTRH+Qbjtyho5bs7bAcETiN7t2719XW1u6nNDBtr39voM/V94vU5/9J36vPhqjvT9FBEMWTiuOCzY1PIiYsncDj3uuiO5MrQHfIzZ3XAG6/Z4RAX/2yT8bPLNk7/vgMiG3Cdwxm6dfFmsDNkD4lnlrEbjer9kasbzP00oEjIvIkcHrTy5bszatOBK5FqKnxDtSkzUcz7M5OZ8afeJwlICMDRBy1T0bzjfmcLNk7eu8oTECe/DBb36L334Pp06SH2O1m1d6cArCQA+5vZjhwVOwT3XDcFoD0KbFksSV7c+sMgUsRar7pm4gJS8weOMzu7HQmLHg9MrGiw0AFCGiJrpjccFRDsvPHv/hFa6hfL9cFL6uE3USNGMRuNyv25haAVKYN5QfSm7ew9Ss6dgzGZ0+ZZMne3DpD4FKcvPm7X0AtxNSGl9idna7kfH2FDBCZPW/AHH/24FF2u+lIsvPPCnlcQN70ClvfUiuB2yhS59ltV629uQVgZttOmF2ofCZXv+KzZkL6RAmzrdibW2cI3Isrg4GG/0JM2sSihezOTldSIm1YQN64qaLDQAUIaL8YhYbOJDv/8NhhmF2ybx5j61sGeZCKUWhYtTe3AEy+8ALMLl3tb9a2X71vbi1kqiulKAJQ0CWCzQ2HEJM29vCD7M5OVyKL2Vd6NY8MEBefbKL2ySxht5uOJDu/+/JGXEBO5Nn6ljsdgvWL81WjVXtzC8D4449BbMJ14KjEzOs7YPMtd+Js1fbm1hgCFyMYaHgGshiHD2R3droyBUxiW+lwDjpAwPbJTH2E3W46kuycXzQPE5CH8fqAi4cNboX0jeuwgR325haAkftGY3zA5K73N6NJIg3lt0lcVmtvbo0hcDFCgYa7UZO2kNRznww3E08uwARkA6dl0QECdfcfGTWc3W46kuycfHAsJiA/PIG9f5ExIzF9mzaVvW/V2ptTABby77eG+jdBbJJY/BTr2Bay7+DqGy9fXrW9uTWGwMUINTV8GzFhibruk+FmdOJ4iD2MFLJHB4jk86CEw316thZy77LbTj9+0BpBJehe+CR7/2KohMOj72DvWzXkFoBuzZdnFyN3DYP0jfJ0Vmtvbo0hcDFO96qvgS3I17ayL0gdGR42AONE5s4x5DCQAYIKtaPmW+5UC7vtdGMhmobZI7VhI3v/qO41pH+a3nBwC8DsXmBN8EP8mQBoKwqib/TavFp7c2sMgYuxqr7+qmBzw08Rk5acL/eC1I20aR4WkFevMeQwkAEid/wMrH+Z7bvZ7acbcweBJ4DfeJO9f3QTiuqfjjcc3AIwtX4DzB6FeI59fOkwGqR//ZuKr8+rsTe3xhC4HKFA4ynEpI0/Np19QerG7OG3YA4ys3ufIYeBDBCFzAXYPhnK+8ZtP91Ir81Q8y0fSbP3L3fsFG49bd/F3j+z5BaAlB4MYYvwkP7sY0ukdFSw9RSMV2Vvbn0hcDmCgca1iAlb7WNrPzP98macAzkXMeQw0AEiPHIIpH/x2bPY7acbk0sWY+bbwN7FtD/c/cPecKxi759ZcgtAKqOHsIVb6oHTa2iU/87sPVCVvbn1hcDlCDU1PAKZtLcFXBEEdGLymacxDqRfL0OvEJwIEFSODhIEHriP3X66MfYoZs8SlTLk7luJsBuOOU+w980suQUg5eqD2GLubPaxJebjOYz/Vky9uK4qe3PrC4HL0RJoaEZN2moeW/uZsE3E99xl2GGgAwSVo0P0MXx7H7nhMMnIqBGYgDxrJnvfSoxNfhjSRyOn6t1GTgEIfRq7ajX72JZIr6MRfUwsmF+Vvbn1hcDlCN3a+LeICUukqhbcC1InUnoJSECeaWw/phMBgk6HouZbpUTXwk9Jp1jpNCvCDlQWi7t/JcJuOAa7Y9+ZGXIKQGii5B3uOQAWfXAcpI/Rhx6oyt7c+kLgcpzo+R+/h1qYdOqLe0HqwmKSVFTlguefN+ww0AGCToei5lulUnfCT5k7HcQF5K3b2ftXIvKGww0nT82QUwBCS6WdCrKPbYmJeXMhfaT0YNXYm1tfCDRAsLnhPGLS0qkv7gWpC/PnojAHmd66zbDDQAeIfDiF6+dL/MlgdWFm5x5cQH7rDHv/SszuB9bWPnycvX9myCkA6akwxA59bnFVTsbUmrWw+Wa2trYIQIEhBAMNexATlk59cS9IXZgBJknNvXXasMNABwjap0enRBH9TCxezG5HXUh5ISHzrffNxf1e3P0rEVp9YvNr7P0zQ04BGH/icYgNqPoG97i2Z2b3fth8M3vDIQJQYAgtzY1PISYsnfriXpC6EJokNf22YYfhRICgU6KIfsamTGK3oy6Mz5sDsYHb1nzxhgNUfza5bBl7/8yQUwBGx93rizUPfZPz6hbT9ubWFgINEAzUj4ZMWpc9DXAzYZvVTewdcSpA0ClRRF/d9jTAzURtVo89/CB73zoycu8oSF/jMx5l75sZcglAEuFhVM1plz31L+7l7tcL0lez1bVEAAoM4Vxz/XcQE5ZI5b+4F6UOpDtZxPhToDfjMJwIEND9QNl32G2pA8NDMTWnEwsXsPetI6kqEaKvRtMruYVcApBO56PiS/qlTezj2pE0LxB9NZrNob29ubWFQAOc61X/JdQCpdNf3AtSB8JysplIkupUgMhs2wkLCLmT59ht6XYWkgXY+KfWrWfvX0fSkxNIf6us0cpFLgGYPXgENt/cePKfngwj+mq2upYIQIEhHP7a1345GGj4CDFp3ZQTzK0s5N5rDfXF5GQzUyPXqQABzQmmxCW3Pd3O7JHjuPGvomQVmrR3CtVfnZLdcwlAaM3pcIp9XDsyuWwppr8DzFXXEgEoMIxQoLEFMWndVBXArcyfjeACsglB5FSAoNe0uBqtxgWvX5neDBRELTH2/nUkUvBmXSh4y5FLACaeXoIZf5fUnO7I9Cuv4tZXOGnK3ty6QqAJgs0NGxET1k11Qd3KzB5c6gAzezCdDBCRO4dC+qtjjVan6bdXopQ/DbW+dEp2zyUAY49Ohox99P672ce0M2bfPAabb5RI34y9uXWFQBMEAw3TIJPWpXdpbiLtm0I5DKMpYEoOw6kAEZuCqtF6P7s93c74Y9MgY+/mQxHhIbdB+qxTsnsuARgZ7f2a0+2Zj2Vh/txMsnsRgALDaAk09kdN2nwkzb4o3UwKIohxDw8faKodTgYIWNobFei57el2wk4pujgtCt0YIPoce2Qie9+MkkMAIvc3J59fzj6m5Rge1BfS58SSJabsza0rBJog2NzwD4gJS3TjSS03MTYZ9DTMZAFxJwMEtEZrssBuU7eymKcMlhh5KXv/yjE+F5P4OjJyKHvfjJJDAOZOh2Dr3GiJSw7CEl8/OtmUvbl1hUATnLzlO5+DLVSp0dolKYExYtyp2oOZdjgZILL7cDVac0dPstvUrfRrabTUqtWYflOye01yT3IIwMyuvbh1brDEJQdhpe9G32HK3ty6QqAPrgw1N7yPmLRmHlv7jcVXJH1AKWBU0DPTFicDBJ0WhQmRLa+z29WtzAJrTputVeokM9t344SIJrknOQQgrOZ0s7n9zU4Tluy+b0/DB61EAApMIRhoOIiYtGYeW/uNuTNhmIPMbN9lqi1OBghoySQX7w3iZmodsOZ0Is/ev3LMnWrBrTNNck9yCMDEvLmQMQ+PGMQ+nl0xs3U7bL5R2jCj9ubWFAKNEAo0LkNM2MiYkewL0q3M7N4HcxSUcNlMW5wOEJG774T0262nA91A2IEjlx++KWTfLZYKRPRdl9yTHAIQV3N6Avt4dkV6PY3y65nd+w3bm1tTCDRCsLnhfsik7dfLlfnB3MDUi+tgjqKQuWCqLU4HiNi0qZB+R8dJ7smyYz7pIcyYa5B+B7bXVpPckxwCMDwMVHP6SffVnG5Pej2N8usUM4zam1tTCDRCS6C+ETVp3VghwA1MLHwSMt7VvCJxOkAkn3ka0/fb+7Db1a0MjxyCEUFzzR044iDstP34sex9M0Kn13chdZ5dBHGS0nAh+p5YaEz8igAUmMKZXo1/iVqwdOqTe0G6kZRHDBKUJo433RanAwS0Rmgsy25bt7H4GhRVgs/kgSMOwnJPDu7H3jcjdHp9546dgq3vzJ432MezEikNF6LvsUkPGrY3t6YQaIRz3/nOb6MWLOV9416QbiSqJFpi/lzTbXE6QFB+SNR8o3JM3LZ1G3OngriAvHMPe/8qEZl7Mh/PsfevEp1e39CDEOei7ONZieSDEX0P3zHYsL25NYVAM6gJlkdM2sTip9gXpNtYyAE3pq9eY7o9TgeIfDgFCxBUkJ3bvm4jNCfbqRb2/lVidj8u96QONxyOb/FYsQIz3v1u1WJPOSwFDuWezFTOPSkCUGAawUDDHsSkjU19hH1Buo2508AnMtt3m26P43uECh+0hgYEIP1PLlvGbl+3MbX2RVxAyr7L3r9KzIcSsPXm5iTYJTq9vulwDGKszSRD5iQ9FUfNNyMZHkQACkxDCcAlmEU7gn1Buo3QJzJVJKflOCUYuW80pP/xx6ax29dtpJOTiLGmgyXcfTPC4g3HbaAbjmefZe9fJTq9vmH1lzV5mAC9wTeQe1IEoMA0Wpob7oVM2r56PLZ3ktAnMgZeEXTmMJwWgPHHpkPGgIQlt33dRto8DgnIDxvblO4Gwm44Zs5g71slOr2+w0NBKWAWL2YfSyOEbvExkHtSBKDANEKB+psgoqSZNu4ay2DuF8KeyBjcJNyZw3BaANKTE8h8uy1QfOLDbWM3MTISdOBowXz2vhklPRlGjEH0/rvZ+1aJjlb6SQJTwGh0oJAz96QIQIFptPRq/DPUwtXh6L6TxD2RqS5LPocApL1TqPmWDyfZbewWQlPArFnL3j+jTC5diplvt/dx/Q2Hk+sbmQJGp5RisSmg3JMGEq+LABSYxvGmb/4mauFSHVLuBekmopLyVvtEhkMA0ulJWKA4cJjdxm4hdD+SBilgSky/vBk2Dm7PPenk+oamgNGoqAAs96SB0osiAAVVIdjcmEFMWqpDyr0g3UI3PpHhEICUPw0VKNIvvcxuZ7fQ7ylgSswePAobB7engnFyfSdfeAEzzpqkgCkxtR6Xe7KQyFe0N7eWEGiIYKBhJ2LCUikm7gXpFlLQRDmGap/IcAhAYnhQX8g4JJ5ewm5ntxCbAsb8gSMu5iNp2LpzeyoYJ9c3LAXMGD1SwJRIr6tR8y175ERFe3NrCYGGCAUaFkEW713D2BekWwjNEVXlExkuARgddw9kHGKPTma3s1votgNHXLyYe7IZMhZuTwXj5PqOThgra1oxH4zD/Hx6y+sV7c2tJQQaItjUMAYyafv0bC3k3mNflG4gvaaFjLGFpLxcAjA+ayZkLCJjRrLb2S2UFDCf0q+pYJxc37RHDTHGuqSAKZFeV4f6N0HGIrl8eUV7c2sJgYZoCdR/HyJOFHNnwuyL0g2kgxqI8bWSlJdLACafXw4ZC932CyEpKWA+pV9TwTi1vrEpYF5iH0ezjNx9J2Qs4k88XtHe3FrCN6irq8spZiuRu51GcKap8U9QCzizex/7gnQDKVULYnzpSU+1beISgPQqAzXfdDoxiKIbDxxxMrnMn6lgnFrf0BQw+/VJAVNibNpUyFhEH7ivor25tYRvUFNT849GyN1OI9hfX//rqAWcenEd+4J0A2nvFGJ8aa9XtW3iEoC5oydxAWPvAXZbc1NSwFxKbCqYDHv/ytGp9Z3eug03vhre0NFhNMRYhIf0r2hvbi0h0BRqgiURkzaxsHqB4hVSmTbYE5m1L1bdLi4BCH1ltF5yT0oKmEvp11QwTq1vXAqYXlpu6Ui/tAk23wrJQpf25tYRfsWv1NbWTlSMKH5AH9TU1PxbXV3dUO6GGUUo0LANMWFjkx5iX5DczJ08B3MIFOyrbReXACTC6oY+tYjd3tyUFDCXMh/1ZyoYp9Z3fPYsyNjqeqgr+8absPlGb0+6sje3jvAllNibrcTeZsW/VwLwffqsR48eX1Dfn+Jum1EEAw0LIIt45FD2BcnNzI7dOIdwOlh1uzgFIJU2QoyH5J6UFDAd6ddUME6t7+h4SQHTntBUMFu3dWlvbh3hS9BhDyUC/0fb9++WPi+JQR3Q0tRwF2TSWkhT4hWmVq/BOIQ+t7QWctWPLacAhCWOldyTxafukIBcZc1pN9CPqWCcWt+wFDBL9EoBU2IxFUy/XpAxodftXdmbW0f4EkropT73uc/9Jn1fEoDdunX7XfV9nLVhJnCuuf47EJHSTPuGqn9K5QUm5s/FiJ07rT1d5RSAqZUrIWMiuSclBUxn9GMqGCfWN+1JQ8WN9MZN7GNYLWGpYGbP6tLe3DrCl1ACcIHiYhKBbQLwKvXzPMVZ3G0zimDT969HLWQdTw7ayejE8ZBxjT0y0VK7OAVgZttOWODwc+5JaAqY1WvY+1ct/ZgKxon1DT3Rr2EKmBLp9TViTKjiSlf25tYRvsRnP/vZ31Zib60Sfz9TX3+h+FP6+eqrr/4t7rYZRehb3/pVNcF+AQkcGuYOs5PhEYMgzsDqCWtOAZg7fgYWODK797PbnIuSAqZzpl95FTYubk0F48T6hqaACcbZx7Ba0utrxJjQ4bmu7M2tI3yNmpqaq7t37/7X11133ee421INgs2NMcSk1fnVkVUWMhdgDtJqjkVOAVhIv+3acdGZmV37YOOaO6lfCpgS/ZgKxon1LSlgOie9vkbNN0qjVc7e3BrCt1DC73dqa2t7Ko6mr7QHkLtNZhFsbtiCmLA6bx63ytyJszBHYLXKCqcAJIaH3w4Zl8TCJ9ntzkVJAdM5/ZgKxon1TeXJEGOqawqYEun1NWq+UeWVcvbm1hC+hBJ8/6D4nuLRurq6derrEfpZl0ogJbQEGuYiJqyu6SPsYGb7LpwjsLjXjVsARh96ADIuVvdG6kzaFiBr+HL6MRWME+tbUsB0TqpggvL7mdd3lLU3t4bwJZTYO6mEX6D9Z0r8NemUB5AQamq8AzJp6elBRt+nB1aYWrUa4whsOO3KLQDj8+ZAxsbPqWAkBUx5+i0VjBPrm8qTIcZU1xQwJV5MBXMrZGySK1aUtTe3hvAllPj7UH35TIePr2r7XBsEe9X/B0SsNDcWq2FwL0oOulnkcAtAnDi2lh9RZ1JqIEhA9sA+3vhj0yFjEx07hr1vnRG9viUFTNeMjLkDMjaUQ7Wcvbk1hC+hhN6ztO+vw2c3Ky7jalM1OBv4fh1qQWe272ZfkByEvea0oeIFtwCEvh4/HWK3vdMk0UviFzGeOqeAKRGWCmZgb1emgkGvb2wKmEPs42eVsamPQMYm+uC4svbm1hC+gRJ8Lygub2MxBYzim23fv9mWEmYNdzvN4PDXvvbLsACyajX7guRgePhAyHgmFi203DZuAQg9ILPL2gEZHUmiFzaeGqeAKdFvqWDQ6zu9RVLAdMXEYlAqmGGdp4IRAeggampqxhshdzvNIj56OGTSUjUM7gXpNKGpTtatt9w+bgFI+0JhSYt9mApGUsB0Tb+lgkGv7+Ty5Zjx1DwFTImpDRth841iS2f25tYPAs2RmQ56bD1R/03kZglNdrzHerJjbgFIdGuSbB1Johcy3zRPAVOi31LBoNc3LAXM3Xeyj50dzO49AJtvubfOdGpvbv3gW3Tr1u3Xampq/qK2tvZf1ddvlsjdLrM4/+zTkAlLgZ57QTpNZLmz/NmI5fa5QQDCyuRNeojd/k5TUsB0zWIqmIG9IWPkxlQw6PUdfeA+zNrVPAVMiU6nghEByIS2PIAFqgOsvv6cvip+pBjlbptZvLflFcyk9WEqmNTKlZix7Gs9BUzJYXALQNoagBijyMih7PZ3mpT/EBKQPZACpkQ/pYJBr+/wYFQKmCXsY2cHi6lg+mJSwVBs6cze3PrBl1BC77ASfsPpe0oA3fZ1rOIo3paZxw+P4/bJ+C0VTHzubIy4GTXClva5QQDS6VLIfCu+tvRXKhhYCpj589j7Zhf9lAoGub4LiTwsTqRf0j8FTImR0SMgYxSfO6dTe3PrB1+ifR7AkgBU+BX1eYavVdXhv/M52ML2WyoYOq6PGMfYFOspYEoOg1sA0pxAzbfc6SD7HHCKkgLGGJPLlmHmmwtTwSDXt6SAMUYnU8GIAGSCEn2JL37xi7/X9v2Zmpqar1x77bV/pL7/gLttZvHxRx9JILGJdFwfMY6JpxbZ0j43CEB6KowKJJlde9nngGPjiEwBs8M7N25+SgWDXN/pLa/jxtEDKWBKJF+NGCNKL9aZvbn1gy9RV1c3Q4m9W9q+v0vxgmJOcRF328yCHAZVmUBMWj+lgoGmgFm/wZY2ukEAQlPBrH2RfR44RUkBY4zZQ/5JBYNc37AUMP2bPJECpkTy1aj51jEVjAhAl0AJv7/v0aPHt664vDyc60EOA7WZ3E+pYHJvnYYt/MzeA7a00Q0CkEinTBHjlHjSP6lgoClgPHR4y0+pYJDrW1LAGGMGmQrm+KWpYEQACiyDHEZi0ZOQCeunVDB0TB+18PPnora00S0CkG4MEOMUm/Qg+zxwipICxhj9lAoGub5hKWCmTWEfNzuZPxeBZ/O6QgAAIABJREFUxQFKM9bR3tz6wTeora19Q3F/JXK30yzIYaTlaYJlJleswIxh31tte0XiFgFIp0wh4mXkEPZ54BTlqb1x0oldxFjFZ05n71t7Itc3LAXM095IAVMipeuitF2IsepYXlUEoIOoq6trNkLudpoFOYzsbuR+In+kgonPeQIyfpRWwK42ukUASioY65QUMMbpl1QwqPUtKWDMMTIKU141Pu/SVDAiAAWWQQ4jfzYMW+B+SQUTnTAWMn6UVsCuNrpFAGZ27oHNt9wp7xxgKEdJAWOOfkkFg1rf0BQwb7zJPm52k9J2IcYq+tADl9mbWz8INAc5jPN5CShWGR4KSgGz+Cnb2ugWAUinTFEBhcQl91yAj5+kgDFFv6SCQa1vSQFjjolFCyFj1XFPvQhAgWWUHIakgqmeheR5mINMbdhoWzvdIgALWWAqmDVr2ecDmhnZsmGKfkkFg1rfkgLGHFPr1sPmWyFz4RJ7c+sHgeYoOQzZVF49c8dO4QLMvoO2tdMtApAISwWzYD5739CUFDDmmI9mYOvTTalgUOtbUsCYY2bPfth8y504e4m9ufWDL1FTU3O1U9fq0aNHTV1d3T7Fltra2oOK15dpUz/1b0HFkOKT6qOrjPz9ksNILJRUMNUyvXUbbMHnW2K2tdNNAjD28IOQ8Yo97P0bDlmr5uiXVDCo9S0pYMwxd8aZPfUiAJmgBNZPFTcq3qh+/GXktZTw26bEXVPbdW9UPx/q+DvdFKgOcUmYqt/boL4fZOTvlxyGPFWonskXXsCMXT/7UsCUHIZbBCA9qYOIGI/lseuM8rTePHGpYGaw961E1PoOD5EUMGZYTAXTB58KRgQgE5Te+kMlskYp0XW8rQzc3O7du/+13dchQaeu8/4V7SqMtJWc697+96gtivNKP1NVEvXzbiPXKDkM2VdUPWGvSMbcYWs73SQAaa8eZL4VU8F4+4ZD9uuaJywVzP13s/etRMT6LiQLsLjgxRQwJTqxRkUAugBKpP2FEmSPKWaV6Dqjfr7brlfE6u/8pfq7Z9t/Rq+B1eff6PDZE3Tddj9fr/5f3Mg1Sg7DqcfWXmR0PCgFzKOTbW2nmwQgNBWMh2rZdqSkgKmOsFQwt/dxTSoYxPqWFDDVMTYZ/5ReBKALcN111/2pElsz2p7MHVbia63iB0qQDbb6tzsTgPQKuJIAVN/fYEYAXrjwITwVDE1WrxL1iiS5ZLGt7SQ7l+zNPWb500FcYNm5m71/sHED5uzM7vDuuGWAqWAK8Sx7/4iI9Z0B7m8uhOLsY4Yisrxqe3tb1RiCKqBE3+eUyLqTXgEr8ZUnAdi9e/evlv6dnsC1vbq1BKdeAZcQHzMCs9CfXtTqVfzixz+COcj3d2zl7h4MH3/0ESwVzLubN3F3D4YfHselNPnvdIq7ezD8OHgONm4/CQW5uwfDOxtehIxZuH+v1o9/8Qvu7sHw3pbNmPmmfOYv/vu/P7mOVY0hqAJKXP1EibD1Smh9T/34S539jvr3p+y4lvo720sl5pQgvKmzQyDXXnvtdapNadWeP1A/Xtl2CMTQE0iaRKU7RtTmcjqZyX1HhmLuGPIVySFb2+qmJ4DEyMghkHFLLJjH3jcU0+twh7XOZ99h7x+KhWgatk4zr25h7x8Rsb4Ts2dBxoxSwHCPF5LI8qr5Uy2f2NsOjSEwCXoC6NS1unfvXqcE3X5KA9P2+vcG+lx9v0h9/p+l32tLAxOmNDDq+4VXmEwDQ3sKJL2EeeqUJZ/s3N7e3IxNwqSC8fJpVlmj1dEPqWAQ6xtW4tLm/c1uoxPVesjOINkh8AvaOwxJBWOeyedBWfL79bI9S77bBGDiyQUiZkwSt7l8PHvf0IzcNxoydvHH3ZEKBrG+w0Nug4xZYsli9vFC0onDWiIABZbR3mFIKhjzjM+aCRkvRJZ8twnA1FrM/iIv33BICpjq6fVUMHavb2SJy/RG76aAKTFy51DQWp33ib259YNAc7R3GJIKxjx1ypLvNgGY2bUXNt+8eMNx8akCPsGsV5lcthQyduHb+7D3jWj3+oaWuNxvX4lLtzI26SFMbGirdiQCUGAZ7R2G5Bgzz/DgfpDxQmTJd5sAzAFTwXjxhkNu0KwxDUwFk49l2ftn9/rObN2OGy8bS1y6lYmFoC0ubdWORAAygg5dUJk2xRP0c21t7T+ozxq422UWHR2GvGIyzkIiD3OQ6Zdetr29bhOA0BsODz7Rgm7RaFdk3qvMHsSl0Mkefou9f3av7+SKFZjxsrnEpVuJ3uIiApAJSuiNV4LviPraq5Tvr0ePHjX0GXfbzKKjw5A6o8aZPXIcF1AAWfLdJgCJuH0y3rvhkENa1pgHpoJJb97C3j+713d8zhOQsbK7xKVbmdmF3FPfIgKQC0roJagecNv377V9fGW777VBR4chaSaMM/3aVtgCz4cStrfXjQIQtU/Gi6daZW1aYzEVzIBmyBi6IRWM3es7OuF+yFjFpj7CPlZOELrFpa1qD7d+8CWo+of68sv0fV1d3bv09ZprrvkN9X2GtWFVoKPDkKcMxpl87jnMWPVvgtQXdaMAhO2T8aCogaWAeegB9r45RS+ngrF7fYeHDYCMVWKxt1PAlIjeUy8CkAlK6K1QIvChtu+LAlD9fH9NTc1S3paZR0eHIalgjBOWAuaeuyDtdaMAhN1wKBYyF9j7Zydh+3Pnee91eTnGH5sGGUM3pIKxc30X0m/D1mVqw0b2sXKKyFQwIgCZQJVAlOA7SE/8FD9SjNLPbaXYtEJHhwE9abjDWycNo+PugYxTbPpUSHvdKADlYIMxyoEZe+jlVDB2ru/cW6dh6zK79wD7WDlF3BaXCSIAmXGlEn5fr6mpqVfi72/Uz5/hblA16OgwJBWMcYYH9YWMU/KZZyDtdaMAxKY22cXePz3GyVs3Zl0x/fJm2Dhyp4Kxc31nXt+BGycfpIApEbnFRQSgwDI6cxiSCqYy8/EczEGmN70CabMbBaA82TJGeVJqD72cCsbO9Z1auRIzTn39kQLmk3EE7qk/n31HBCAHampqbqitrX1N8bzij9v4E/rK3Taz6MxhSCqYyiRnDwskBw5D2uxGAUhE3XDE581h75tdlMNZ9jAf8W4qGDvXd3zubMgYRUaPYJ8DThKZCiZ/8pwIQA7U1dUdV2JvlhKCf6e+/7P25G6bWXTmMCTdRGWSs4ct7HAS0ma3CkA53VqZsibtITQVzHPPsfbNzvUdfXAcZIz8kgKmxNzpECxOZHfsFgHIASX+PlBfruRuhx3ozGHI04bKhKWAGRCApIAhulUAJhYtxIib4bez980uwkSyB/MlVqJXU8HYub7DwwdCxijx1CJ2+ztJ9J56bv3gS1C6FyUC/5W7HXagM4chqWAqk5w9Ynwi946CtdmtAhCaCib9Nnv/7KDsy7WPuFQw97D2y671DU0Bs34Du/2dJrLaEbd+8CW6dev2u3V1decUX1FCcEl7crfNLDpzGJIKpjIp7xdifOIzHoW12a0CMLN7P2y+5Y6fYe+fVcpBGXuZXOrNVDB2rW9aMzD/76MUMCWi9tTHJo4XAcgBJfTWKPHXQvsA1dfJ7cndNrPozGFIKpiuWdxHpJw9YnwoOKHa7VYBCL3h2LaTvX+uHh8fpYApEZoKJp5j65dd65vWDGx8zkXY7e80kft3ufWDL6GE3g+/+MUv/h53O+xAOYchr5zKMx/LwBwkBSdUu90qAAu599QNR0/IeKZWrmLvn1XKlgx7mT14BDaenKlg7FrftGYg49O3Z3Gtc9vfaSK3uOyvr/91bg3hO9TW1h7p1q3bH3K3ww6UcxiSCqY8s4eO4QKICk6odrtVABJhqWDm6p8KRg5l2UtoKphX+VLB2LW+KX0SYmwio/yVAqZE5A3c6eYbv8KtIXwHJQBH1dXVvakYqKmp+WZ7crfNLMo5DEk7UZ7pV16FLWgKTqh2u1kAxiY/DBlPSmfB3TerlLVoLy+mgglAxpQzFYxd65vSJyHGJjblYXbbcxC5haOlV8P3uDWE76CEX6wMo9xtM4tyDkOeOpRn8tlnMWMzoBmWAoboZgEISwUzbCB736wS9zTefylgSsSlgnmMrU92rW9Kn4QYG7+lgCkRucUl2NwwiltDCDRGOYch+47KMz5zOmRcKCgh2+1mAZhatwE233RPBSP7ce0nnbZHjClnKhg71nchcwG2DmmNc9udi6g1HGxufJJbQ/gW11577XXdu3f/P90UuNtSLco5DGQGc91TwUTHjoGMS/yx6dB2u1kAZvYAU8G8pW8qGDmRjyEsFcygvmx9smN9U11omN9Xa5zb7lxEJXIPBRq2c2sI30EJvz+qq6vbo/gzxVzb171f+MIXruFum1mUcxgSeDpncf/QwN6QcUkuWwZtu5sFYP5sBBd4Xt/B3r9qKSlgMPRiKhg71ndm+y7cuJz1XwqYElFbXBST3BrCd6itrX1Rcd7VV1/9W/QzfVUCcK7ieu62mUVXDgP36mke+4Kslvko8AThK69C2+5mAVjcJ9MXs08muWIle/+qpWzFwBCbCuY4S5/sWN+UGBwyLn38mQLmk3GVVDDegRJ6b9fU1Pxq+8+6dev2a+rzC1xtqhZdOQxJBXM5sweP4gLHoaPQtrtZABIpTQRiXONzZ7P3rVrKYSwM8+EUbB1zpYKxY33TvlDEmNDDBG6bcxJZ7ehMU+OfcOsIX6G2tjbSvXv32vaf0c9eOgVcdAaSfuIyQl8dRTPQtrtdAMamTIKMq86pYGQNYujFVDB2rG86GY4YE0rzxG1zTkoqGA9BCcAxJPbU12E1NTXfpq8kCtX3d3O3zSy6chjy9OFyJpc+gxmTgb2hKWCIbheAlCYCInaGDWDvW7WUp/A4Ru4dBRlbrlQwdqxvujFAjAntgeO2NyehqWAC9aO5dYTvoARfb8WtimfavvZWH1/J3S6z6MphyP6jyxlDpY8YOwbedrcLwNR6YCqY1Hn2/lVDSQGDIywVzDieVDBW1zfdlNPNOWJM6GECt725iVrLoUDDQm4dIdAUXTkMSQXTySK+5y7IeMQfnwFvu9sFYGbvAdh8y711mr1/Zikn8bH0WioYq+ubbsph/n63f1PAlIiqdiSpYBxGTU1NQ7du3b5M33fv3r2utrZ2V11d3Xb6nrttZtGVw5AA1GE8aN9Q/ybIeDixb8jtAjB/LooLQBqmgpEbMCy9lgrG6vqmOYEaD9oDx21vbqJSwQQDDSluHeErKMEXvu666z7X9v1LirOUKJykRODr3G0zi0oOQ1LBfMp8KAFzkE6cHHS7ACzk328N9b0VMr7JFSvY+2eWsgUDS6+lgrG6vummHDIefW4pPkzgtjc3U+vWw+bb4W9/+ze4tYRvoITeh/SVUr8o8fcBfVU/XqU+f5e5aaZRyWHIJvRPmd1/CBcwjuADhtsFIDEyGpQKZs4T7H0zSzmEhSU0FcxrWx3vj9X1TTfliLHwewqYEpHVjiQVjINQoi/Zo0ePGiX4vq++30mfUV5AEoPMTTONSg5D0lB8yvTGTbAFXEjk4e3XQQDGpj4CGd/ohPvZ+2aWsLV3x2D2vrmBXksFY3V9xx6eABkLeojAbWs3EFntqCVQ/31uLeEbKKE3SvFHRCX8bqLPunfv/s/q5wPcbTOLSg5DnkJ8ysTixZiAPLi/I+3XQQAmFj+FGeOh+qWCkafveMJSwcya6XhfrK5vujFAjEVi4QJ2O7uB0FQwTQ1juLWEr0AHPhS6t/9Z8aucbaoGlRyG7EP6lLCnUw/c50j7dRCAqfUbYfOtkNQrFUzkzqGYgKzh/lsUvZQKxsr6LmQuSAoYBxgZNRzj3wINi7i1hEBDVHIYchKx3eIdfQdkHOJPPO5I+3UQgFlkKphjp9j7Z5RyAt8ZohK7c6SCsbK+cyfO4vz8rn3sdnYLY1NAqWCaG3dwawmBhqjkMCQQtY0D8oTqCy840gcdBGC+JYYLRFu3s/fPKOXGyxl6KRWMlfWd2bYTNg6500F2O7uFwFQwaW4tIdAQRhyGpIKhHHW4DbxOCRMdBGBRaPfTW2jbQezWixb2/rmF2QOHYePsdCoYK+s7uWIlZhz69JQUMO2YWoerdiSpYASmYcRhyGZ07BF+p6pU6CAAibBX7bNnsffNKOXwlTP0UioYK+ub0iQhxoD2vHHb2E3M7HkDNt/O3lqv3RkEATOMOAxJR4FN4llIv+1IH3QRgLDDNuPHsvfNKOnkpN/XnBP0UioYK+s7OmEsZAxozxu3jd1EZCqYYNNNP+DWEwLNYMRhyNMIoAgePtCxPugiAGHpdobcxt43o0Q9dadcb9x9cxu9kgrGyvoOD+kPGYPEU4vY7esmFlPB9MWkggkFGu7m1hMCzWDEYUgqGOBr8IcecKwPugjA1IaXYPOtkCyw988IwyOHYAKyRvtunWLMI6lgql3flIQetd5SGzay29dtjIzCVDuSVDAC0zDiMOREIi4nW3zeHMf6oIsAzO4/CJtvuaMn2ftXiYXsO7icbBqdvHeKuFQw/RztR7Xrm8pQotYbrWVu+7qNqFQwwUDDTm49IdAMRhyG31PBFLLv4gLyqtWO9UMXAYhMBZPeso29f5UIzcmmyQ2Xk0xvegU23gUHU8FUu77Tr26B9T8fjLPb122k1+KIsQ42N2a49YRAMxh1GH5OBZM7FcQF5O3OBWRdBODFVDC9IOOdXL6cvX+VCM3JdkpysnUkNhXMW471o9r1nXz2WUz/+zcV1zK3fd3G1HpcKpjjTd/8TW5NIdAIRh2Gn1PBZHbuwQVkB3Oy6SIAiZExIyHj7VTVFSvE5WS7pfg0m7t/bmM+nISt7/Tm1xzrR7XrOz5zOqTvkXvuYretG4lMBRPsWf/n3JpCoBGMOgw/p4Kh19SQBUunoLPOnYLWSQDGHp0MGXOn6i5bISwn213D2PvmRhZTwdwGSgWzbKlj/ah2fUfuGw3pO9VZ5ratG4ksKtASqG/k1hQCjWDUYfg5FQy9pkb03Wnxq5MATCwBpYIZ3J+9b5VIIhXRd8nJVp6oVDAxB0VQNesbmgfRQfGrE5FlRUNN9Q9wawqBRjDqMPycCiY6cTwmOEx60NF+6CQA0xs3weYbpb3g7l9XDA/uB+l3YvFT7H1zK+OPTYOMuZOvQatZ39BKKK+8ym5XtxJV7SgYaHyeW1MINIJRhwFNBePgQYhqGB4xCBOQn1zgaD90EoDZ/Ydg883NqWDy8Rys35Rfkbt/bqUXDkJUs76hB2AOHWO3q1uJ2uISCjS+ya0pBBrBqMOApoJxMBWKWVKZNlhAfnGdo33RSQBS+gjUuKe3vM7ev3LMvnkMF5CVqObun1sJTYXSEnOkD9Ws7/RLL+P6Hcuy29WtTD7zNGTMg80NH6qwfiW3rhBoAjMOA5UKJj53NvuCLMfc8TMwB0mv1Z3si04CEJoK5nn3poKh12awgBxKsvfPrcweOYFb53vecKQP1azvxJIlkD6HB/Vlt6mbicw9eabXD/6IW1cINIEZhwFLBTN+LPuCLMfM6ztgCzV3JuxoX3QSgMTI3XdCxt3pGq1mmFy6FDPfBgSKG/65++dWUolA1Dp36kl/Nesbdtp+3L3sNnUzswePwubb2V43fYNbVwg0gRmHkVi0EDJhadM794IsR1xOtp7FwuBO9kU3ARibNgUTnFycCiY2fSqkz5Tqg7tvbmd46ADI2CcWOrPXt5r1jTqMoEO+TU7mYxlMXGkuHgQZyK0rBJrAjMNAZjB3634RWE62UcMd74tuAjDxNOj1lItvOGBPPWdOZ++b2xl9cBxk7GMPO3Pa3+z6vpiOpCekz8kXXmC3p9tJr8kh8TTQOINbVwg0gRmHQYW9IRO2mU6MHWVfkJ0Rl5NtkuN90U0Apl/yVyoY6L7H555j75/bmZg3FzL2lEXAifabXd/5s7iExJmt29nt6XbSa3LE2AebGzZx6wqBJjDlMEIJmMNIv7yZfUF2JO2ZCt/eB9JfKgjudH90E4DZN96EzbfskePs/etIOi0KW1+vbWXvn9sJq/ijSNkE0O03u74zu/fD+pt76zS7Pd1Oek0OGf9AQ4hbVwg0galXBsis8c88zb4gOzIfxe3TSK3f6Hh/dBOA0BsOFwqizN4DsP7SKVfu/rmd0Jrfb52Bt9/s+oZVd2p2RvDqzuSKFZjxDzT8/HR9/a9wawuBBjArCKJjx0AmLZ1G416QHZk9eAQXkBlysukmAIs3HP2bIOOffP559v51ZGrdelxAThbY++d2QpPdO/BK1Oz6psMpiL6Ghw9kt6UOzGzbCZtvwabvX8+tLQQawKwgiD8+AzJhI6NHsC/IjoQmSQ07n5NNNwFIpFJaiPF3YyqYxMInMQF56AD2vulAOpUPOxSxHJ970uz6plKUiL5GH3qA3ZY6MHfiLCy+tPRq+B63thBoALOCgJ6cQCZt357FaiPci7I9E0sWY/o6oJklJ5uOAjA2DZMWJXr/3ex9u6yvqID84Dj2vulCuhFF2MCJGw6z6xtW4nL+XHY76sBC5p3WUO+bITYINjWM4dYWAg1gunTQlm0YUaSYOx1kX5TtSSd1vSQ+dBSAqJJJoYG9XZcYOXzHYExAnjeHvW+6MDb1EdCavwfedjPrG1ricvUadjvqwvDIIRAbBAMNi7m1hUADmBUEdLoL5ThoEzb3gmxPWOk7ptePOgrA9CZvvYYvx0LmAuxpgARk40SVRnPihsPM+s4dO+UbP+5moqprhZob9nJrC4EGMCsIoHeOq1azL8hP+pl9pzXU5xZIP7mSpOooALMHDsPmG+W15O5ficj9QFkJyIYJveGIpKFtN7O+6RQ8qp9ue5PjZqKqawUDjW9zawuBBqhGEKD2jsTnzmZfkCXmTp6DOUiqL8zRJx0FIDYVzwb2/pWIrDmdl4BsmNCT/+pmBtl2M+s7+eyzmH72db7Epc5EVtc6XV//+9z6QuByVCMIYJvVJ4xlX5AlIo/o09Mejj7pKACLybhBJZPo1C13/0qE5QTrc0vr+by7Dle5mfloGrbuqbINsu1m1nd8xqOQPkbG3MFuQ52Y3YerrhW6tfFvufWFwOWoRhDA0lUM7s++IEuEBeTeNxdPf3H0SUcBSISV43OoRqsRoqoCxMeM0M7enCzmnkRV/1myGNp2M+sbVXOaTu1z21An5oNxTJxRbAk0NHPrC4HLUY0gSK3DPbbOx3Psi5KICsiRkUPZ+qSrAIzPeQJii/Dw29n7VmJ03D2QPmYem6qdvbmJsgWdMEa22+j6vlhz+lZIH5PLlrLbTycWbzhuw1TXCjU1PMKtLwQuRzWCIIssWXXoGPuiJMKCwOSH2fqkqwCkw0Go+VZInmfvXzEIDOwN6d/by5dpZ29uwm7+Rg2Httvo+s6dCcPWU3rzFnb76cbIfaMhtggGGtdy6wuBy1GNIEA+tk6/vJl9QSIDcmLxU2z90lUAQmu0Hj3J3r98KAnr3/s7tmpnb27SKX2IPfpgk90bXd+ZXXth801qTptn/LHpGHsEGk9x6wuBy1GNIEA+tqbEv9wLktI1oBxkeiN2I3hX1FUAev2JBXIj+I/PntbO3txEnsjOnWqBtdvo+qa8kKj+ueGJum5EncgONjf8dFV9/VXcGkPgYlQrCFCPrWOPTmZfkNk33oQ5SHQqiK6oqwAs7lnq6909S6l162Hz7aMP3tfO3tzMHT8DswdlF0C12+j6js+dA+mbm/bU6kRkTsZQ8/d6cGsMgYtRrSCIz5wBmbCR0fxpBOgpHWpBUpoJrn7pKgCJsFOL0/lPLSYWzMcE5EF9Wz/++GMt7c1JZFUWZBJ4o+s7On4sZi09PIHddjqStqGg4k2oqeHb3BpD4GJUKwiSzz2HmbAuSCSaeGoRpm+392GtP6uzAIzB8paNZO9bdOJ4SN+i4+/T1t7cRNVlRpaBNLq+w4P6QfqWWLiA3W46kl6bQ+KNYrCpYQy3xhC4GNUGiPSW12GTNnc6xLog6aQuJCCPu5e1XzoLQC9XLggPG4AJyHNna2tvbsYmY2q00tYZVJuNrO98DFhZZ517KuvoxvDwgRCbBAMNz3BrDIGLUW2A8HIxccrVh+gXpZfg7JfOAhBbu5TvhqOQyOMC8uo12tqbm3RaH2KX/k3FPa2INhtZ39BSdy6qra0b6fU5wiZKAB7k1hgCF6PaAFFIv40LXCtXsS1EqtIB2/+zYiWrk9FZACL3yXDecGTfPIYLyLv3aWtvbqY3vQyzS/5cFNJmI+ubytHB+hVKsttNVyYWLYTYJNjc8KEK81dy6wyBS2ElQIRHDIJMWs4nZbm3TsMcZGb7LlYno7MAhN5wrFrN1i/KewkLyOci2tqbm9lDR3F+QAlzRJuNrG/Yk80Bzaz7m3VnasNG2HwL3fqDz3PrDIF5XFlTUzO7trY2rBhU3w8p94t1dXVxxbPq944pHlW/W2/0IlYCBOqxdXTsGLaFCH3VeBKXA8wIdRaARNgNx5wn2PqUWLIEM9/6N7WeL7yvtb05WYjnYH6AXs0j2mxkfcP2N99/D7vNdCalB0PNt1DzTd+0R5IIHIMSdAEl5rbS91/84hd/j0Se+vn6Mr8b7d69+1eruY6VAJFY+CRmwt4WgO2TqUTKCwfpU59bWgtZXBUAI9RdAMYmPYgJXg/cx9enKZMgfYrcO0p7e3MzPBRzOCc+dzakvUbs7dX9zbozH8UdzgkG6kdY0SICBiixt6mmpqah3c9TFR/q7HeVAIxdd911f1rNdawEiNSGl2CTNt8SY1mIsWlTMAEZXAfUCHUXBKh9MmHG9DyRu4ZhAvLMGdrbm5vRhx6A2AZ1w1HJ3tD8hitWsNtLd6LS8wSbG5+sVocImKBE3Qkl+P6m9LMSg4PUz8+U+d2Y+re31Nfjiouuueaazxq9jpUAgXxsjdonU4mRUSMg/SFhye1gdBcEyH0yHAm6oQeOnl+uvb21cYyJAAAgAElEQVS5mXhyAWa+gW44Ktk795aeFU78wuiE+yG2UQJwt3VFIrAVSrDtVzzfnkq8vU1fldj7fCcCcHA5AUi/3/btVer/TVG/97LRdpDDuHDhovMwy0I8C3MoqdWrq2qTFZ7PvVN8VQsJyMuWOt6fjiQ7W7E3N6El+t445Hh/8ieAAfn1Hdrbm5vp9Rtg9ilEUra3t5K9M8DcrfnTLez20p2J+XMhtgkGGi5YEisC52HmFXB7dOvW7Q/V731g9DqtFhEFJbHNPzXfatNM46fJBMxBfvjGXsf74zV89N57MPu8t3Wz4/358OB+WH9+mko63h+v4UdncLlOf3T6pOP9ubBmBaY/fXu2fvzRR473x2t47zVc6qFQff3V1WoRAQPq6uqa2w6BfKZ0CEQJwq90/L1rrrnmN7p37/47pZ/V79yp/t9Oo9ehiWflCUEMtU9m3D2O34FB75CPn2a/w9T9idD58x8U9+sh7JNYMM/x/qSeB5VT7H1z8Wm27vbmJj2lQ/kDerpod3sr2Ts+bTKkL7RthttWXmB27xuw+RZsbvgHe5SJwCl8pi0NTEQxpATg0NI/qM+/rbiQvr/22muvo9Qv7fYArlOC8ItGL0IOgyaf6/bJMOSVgpUbUwGZ9ntx7zEhO1u1NzepnB7CRtEJYx3vS/yx6ZiAfNcwz9ibk+R/QrAbjvm2t7eSvVEHjmKPTma3lReYD8Yx8ae5WBP4doRIEWgOqwEiBdwnQwvCyQUYmz4VGpC56QVBQCk0EDbiOAkcGTMSE5CnPuIZe3OTTuwibEQnjO1ua1f2hp4AXraU3U5eYPGGY0AzxEbB5oZZ3FpD4EJYDRDIjfmZPfsdXYCR0aATwC65Q/aCIEitWQubb06WsqKckKE+PTEB+ZmnPWNvbsJuOIbcZntbu7I3snY7Jc/ntpNXSAm1ETYKBhq2cmsNgQthNUAgE1hSsHdq4V0MyKATwEvdcYfsBUGQ2XsANt/obzvVj9xx3Ang9Cuvesbe3KSqHSg75eM5W9valb3Tm1+D9YPmMredvEJKqI2wUbC5McOtNQQuhB0BIjwYk8AyPneOYwsvd+IsLiC/uoXdsRC9IAjoKR3KTqm1LzrWD2TJweyRE56xNzcpHynMTgcO29rWruxNT4Uh/ShWOOLf3+wVplaugthJCcCfcWsNgQthR4CIPjgOMmmdLNGV3roN5ujp9Qu3YyF6QRDQPhnUSWBUia7OSE+FIfONDhyl3/aMvblJFYlQfiG1boOtbe3K3rEpmBrAtG2G20ZeYmbnHsx8CzR8zK01BC6EHQGCTrRBJq2DG/OxJ4AvsDsWolcEAZ3YRdiKThg71Qc6qAEJyHcO9Zy9OUk1yUP9myC2SsyfZ2tbu7J3+I7BkD7EZjzKbiMvMXcmjIlDiqvq66/i1hsCl8GOAJFatx42aZ3amE+ODB2QuekVQYDKmO9k6qHIyKGYgNzuwJFX7M3N6NgxEFtFx9ubeqicvQup8zD/nHzuOXb7eInFG44BAdvtFAw0vq3C/ZXcekPgMtgRILL7D8IcjFMb8yNj7sAE5LaUHG6gVwQB9IajJQZvP72ihQXkdik5vGJvbsZnz8LYa2BvW284ytk7e/g4zj9v3c5uH68xDngYEQw0LOfWGgIXwo4AkQ/jMubTKTz0gsOm5HiG3aGU6BVBkN1/CBfQdu3Dt/8ILiCnt7zuOXtzE3oS2MZcp+XsnX55M6z9uZMt7PbxGhEHxIJN9b25tYbAhbAjQBQ35g/qC3EwdCweveBybwFTcmx2xwlgolcEATT10KrV8PZDA/KJs56zNzehqYdsvOEoZ+/E4qcw7e/bs7WQe5fdPl5jIZEvPh22y07BQMOF0/X1v8+tNQQuhF0BArUxP3LfaPiCI5EGC8hHT7I7lBK9JAjCg/tD7OXEDQc0IGc/Dchesjcn82Fg6qGVK21rZzl7xyY9hPHNd9/JbhuvMr3pZdvsJE//BGVhV4CgE22YoHarust8D7rYEk8vwbS9XUoON9BLgoBKaSFsRhv+0W2PPfygIwHZS/bm5MU3HKBcp48/Zls7y9k7PHwgpu2PTWe3jVdJcy72yETLNgoGGnZdIYc/BOVgV4BIrd+IEVHNtM/kHHSx2bHQOg3II91zApjoJUGQWLgAM9/6NxVP4iHbHh42ABOQZ14akL1kb26ibjgi99xlWxs7s3fxdSLILyeXL2e3i5eZj6Zbo+OqLw2nxN8eefUr6BJ2BYjswSMwR9N+YzuC4WGYO+TYtCnsTqQ9vSQIUhuANxxnwrB252NZXEB+4QXP2pubsBuO4hsOe/bRdWbv7MGjsPmW2baT3S5eJ+WQjc+cUYV9Gtbtr6//dW59IXA57AoQ0DvNpbiTtPkY7kCB23JkeUkQIG84kIGNyn/B2r19t2ftzc30xk0wu9n1hqMze1O1EVi7TwfZ7eIH0utgeggSvb/y08Bgc8Ohc4Gbvjvhiis+w60tBBrAzgAByzY/5WHY4oKmFHHZHbKXBEEhnoPZjarCoNqdWg8MyB2eXHrJ3tzMHjoGsxuVobSjjZ3ZOz5vDqbd/W6Fb5UQdjIP3zxWzPVJe0cpkXioueFIMND4vBJ+95/tddM3rpD9fgIzsDNAoMpbhUcMgi2o1NoXcQH5dIjdYbSn1wQB7NU9MHk37LBUJ3sXvWZvThaSBZifSC5bZksbO7O3kadG1TBy7yh2m/idZGdu/SDQHHYGCLozQTlJesWMWETxOU84FpC56TVBEJuEOU1LT7JRbY4+cB+kzZ2dXvaavbkJe8PRrnyfFXa0N7KOcXzWTHZ7+J0iAAWWYWeAoFcZKAFIe6cQiyh6/92YgKzuvLkdRGcOw0uCILEElL6nGXPDUQzIt9lf57MYkGfP8ry9uRmbMgliO7vqhXe0d+5UELY+nKjQJKxsb279INAcdgaI3KkWnMNZt8H2BQS9Q547h91BdOYwvCQI0q/iEngjbjho07yTAdlr9uYmHUaD2I/yhabOW25fR3tDb8gdqtEu7Nre3PpBoDnsDBCUsDnUrxfE4STmzbV9AUED8ovr2B1EZw7DS4KAyp7pZD9kQM7s2e95e3MTUaP1E0F18Kjl9nW0d3IpbksOlWPktoffKQJQYBl2Bwgq3YZwONFx99q+gDKv78A59DfeZHcQnTkMLwkCyp9GedQQ9ovPnW17e2FPkCggR9Ketzc3c8dxNcNT69Zbbl9He1P2BERbKZE5ty2EIgAFNsDuAEF7kSBO8raA7Ycq6PQdLCDHc+wOojOH4TVBALvhAJSEi03GVJwpF5C9aG9OUp3lUJ+eEBvSYTSr7eto7/Dw2yFtpcpJ3LYQigAU2AC7A0RqzVqYqLK7QkNsMugOefhAdudQzmF4TRDAbjj69bK9BjWqBBwJS7/Ym5tUbxlhQ7qRsdq29vbOI/NkPoNLzC80Z29u/SDQHHYHiOy+gzDHQ69s7VxA4aHOBmRuelEQQPM42liDml7RwgJymUo5XrQ3Nyn9CcSOfXsWnzBaaVt7eyMT3KNLcwqN25tbPwg0h90BgjYHwwKdjXee+XAS2M6n2Z1DOYfhNUEADXSvbbWtnZk9b+DaWaaShBftzU3oG45jpyy1rb29sTdGLex2EIoAFNgARICAPVl7+EHb2pjZtVcL4WC3w/CaIMC+6rJPyKdWrsIF5DI1Wb1ob27S4S6Y33h5s6W2tbe3TlsjhNXbm1s/CDQHIkDAKjQM6lcsjG1HG5PPL8cF5FPuLJLuVUEA2+xu4w1HfOYMzHzr4nCUV+3NSUoQjvIbiYVPWmpbe3uj9ioiDkcJq7c3t34QaA5EgEg8javQkG+J2dJGKr8EaeMA+08r2+kwvCgIUBUawrf3se2GIzL6DkxAfuA+39mbm+GRQzC2nDDWUrtK9j6febuYXBrRRkR6JGH19ubWDwLNgQgQ0IS323ba0sbwiEEYJz7emhNHOwwvCgJkDer82Yjl9hXSuICcWDDfd/bmZmzaVMx8s3jzWLJ37s2jsPXgxgT3fqUIQIFlIAIEpWtBOSAK9lbbl4/hDqpYfY2DdhheFASZrdth9qS/bbV92YNHYO1Lb9zkO3tzM7kcuH3kdKjqdpXsnV63DtY+VE12YXX25tYPAs2BCBD02iw0sDfEAdmRhDSz9wAuIFvcyI12GF4UBMgbDtrOYLV9yJOj2SPHfWdvbkIPkJU50W2EJXvHn3gc0z6qWZwssI+/8FN7c+sHgeZABYjoQw9AnFB4cH/L+7JSK1fCHHjurTPsjqErh+FFQVC84bi9D8Se0YnjLbcPdgCEAnLmgu/szc18CJdCysoNR8nekTGY/aaR0SPYx154qb259YNAc6ACRGLxYpiTzAfjltoWf2wapm39bi3Wp+V2DF05DK8KgujECRibDuxt+VBP5K5hoIB8h2/tzUm64QgP6Q+xKd04V9susvMvfvIT3AGQxx9jH3vhpfbm1g8CzYEKEJQLDyUAMzt2W2obKiBH77+b3SlUchheFQSUsw8136zsy0KmDaGqFH61Nzdjkx7C2NXCQRCy849bzsLmGyWX5h534aX25tYPAs2BChCUCw/liJLPPlt1u5CJgxPz57I7hUoOw6uCgMoEouxqpfRVFrjftNKJTC/bm5tUlQhl19yJs1W1iez83qsvw9pFh5m4x114qb259YNAc6ACBN3FhgY0QxyRlVq7md37cUKhixOZbqCXBUH+XARmV9rOUG27kitW4ALym8d8a29uIk+eV3uQjOycXzAb0y7ab5o6zz7uwkvtza0fBJoDGSCiD46DOCMrCXqTzz2HC8hHTrA7hUoOw6uCoLgva1BfiF1pHlfbrti0KZj51qdnayHzjm/tzc38uSjMj1T7JqFYAu6ekZA20cES7jEXXm5vbv0g0BzIAJF4ahHMSZarf1qJsckPswVkbnpdEKBKEFrZl4UqUxe5b7Tv7c3J4g3HYMxBECO27ZSp87gDIE88zj7mwkspAlBgGcgAkd68BSYA06+8aro9F58S9cM47XtHsTsEIw7Dy4IguRRXEaSafVn5cArWnvi8Ob63NzdRJQhDfW7pMr1POWb3H4TNN6kA4j6KABRYBjJA5E62wBxSYv488+1BJgx2+QGQksPwsiCgMoEo+6ZfMr+/M7NzD2t7vG5vbiafx1UEyR46aro9KWCFkmraI8RSBKDAMpABongQBFQRpJonbsjUNG6uANLeYXhZEORbYjD7xuc8Ybo9yBrFuWOnfG9vbmb24A6UVZNyhQ7HQdpDB0DSb7OPt/BSigAUWAY6QMQeBu3LquJUWmLRQlxAPnmO3SEYcRheFgTQfVlVVEFAVcMJ9etlKOG41+3NTWRKqfjM6ebmvrrZDoOq4UTuvpN9rIWXUwSgwDLQAYJy9qGcZPaNN021JTruHkxbbKgW4ZTD8LoggD0FUaSAb7QdJNBC/Zsg7Yg+cJ/Y2yVEJZUPjxxiqh25U7jtNtU8/RbiKQJQYBnoAJHZvQ/mmCjHmtF20KbqUN+emIA8cQK7MzDqMLwuCJD7smguG20HpQRCtYOeZIu93UEqj4aycz6cNNwO2oKCakc1+1+FeIoAFFgGOkAgX5PEpj5iuB30tBDVDjp9yu0MjDoMrwsCZOWN5LJlhttBe7hgAXnzFrG3S0inY2F23rrNcDvic+fA2lFtZRIhliIABZbhRICIjBoBcUxUkN1oQugk8ISc1drETjoMrwuCQrIAy4Vm5klvfMajuIB8Jiz2dgmpGgvKzomFTxpuR2QMJgG0Lttb/EgRgALLcCJAUBJRWDA8HTLUBliSYMV8JM3uDIw6DD8Igsg9d2FsTQmhc+9VvH7xMMqwgZA2mLnp8Yu9OUnJ3ykJPMLWRjMdFOgtC+imh/wm9xgLO6cIQIFlOBEgUhs2wsRX+qWXK16fgjYFb0hAvmMwuyMw4zD8IAgoJyNqvmWPHK94fWQ6GiotJ/Z2F6Njx2DsTZkOEvmK16c3EKj5RqUzucdX2DlFAAosw4kAkXvrNMxBxWfNrHz9oydx13/8MXZHYMZh+EEQUJUYlL1Tq1ZXvv6ruAo4qdVrxN4uI7LkZWb3/srXX/wU7vp7Kl9fyEMRgALLcCJAFJ/A3QZ6Ajf89oqvxJAb8unpJrcjMOMw/CAIaFsAyt6xKQ9XvP7/b+9coKOozjhOoKJVW+sRxIYmIU+rVltrW09b23JsSw9W9CDsBgjZCBSPyEsRwRZU5CFqpRyq4IPDQ/BBWxRbUKu8VUAeiiJIkk12k012s+GhUFtL8ZF+32YWhpDdzO7M3W925/875392nntn5t6595v7+K7KDvnc5wzxbS+pnIHGyAAznjtYVfhGaiAhGcEABKZJVQGhzCkuKby/Nm7YfpUd8tNohJxTDIJWh9Bq5nyOdIrvoB9g7R1j1IQ9oqylOdSxA2inxbe0uA+wqvzFN21q/LROBpqq/n+1k24Xf7ZQbMEABKZJVQGhclqseNOwRTzkKzIG2PN+Oo2Qc5JBwC6CVKU39vEXK9xwpU+hMTAF8W1T1U4cpybeh5fFnYZN5XzTXJMt/Vyh2IIBCEyTqgIiqNA/G48yjhUuz5mqKtxE/BDaQU4yCLivnKp4j9cPUKVD3sDSJYhvm6pu/qPK4j1eP7z6RYuUhct9WaWfKxRbMACBaVJVQPBXrCp3CTXjR8XsB8iFtYQhYEc5ySBQOfAnXj9AHpSkzBDY9Cbi26ZSafjXL14UM1xlI5BJ4eo68ecKxRYMQGCaVBYQPIepqswqlj9A/0x1/v9CO4x3yLeDnGQQcNM899dTEvfsD7CdvniRvofj1Pj/M+oSxKnxLS12zq0qn2G/lu2FGfaH1PX/mzBG/JlC8QUDEJgmlQVE4OmlyjJJnpKpbXgRJ60jhqoJ83flCXXIt4OcZhBwTZ2q9MZTC7YNr2lftbLwuKYH8W1ftTr/vkVZ/Id9pzubb3x9vbLwuElb+plC8QUDEJgmlQUE92VRlWH5Z5/eLBfasl1dgTz9XvEMIJkMw0kGgcrm//b646mcF7Z+8WLEt81VN/cRZfHf+Pq608NTOMOS0fmmITnBAASmSWUB0dxwoMU7bLCaTItr5IKHTwkvsFRdjWNgxQrxDCCZDMNJBgGP1lUV/+01y/lnTVcWnhGHwE6Pb2k1rnlZWfzXPfbnU8KKeDcYPVJZeOj/Z3/BAASmSXUB4bvnbnWF5JvbTglL2ZywFcamBLObnGYQtE4BWKGukPQGTobFHzfDy9SENWxI5P8R3/aWyikAuXlZ73JKpXcD9mMp/SyhjgUDEJgm1QUEN52pyrh4SqZoOEoz4zTz/6fPMJxmEHDXAFXpoHHNKyfCCW5QNx+r777E/P85Ob6lVXvnWGXpQP/RGVjxF2XhtK1thOwpGIDANKkuIEJbdyjLuGonjj8RTsNLf1cWjv+Rh8Rf/mQzDKcZBCqnAeQZZqLh1C1QN/1bYNkyxHeaqP6JxxWmg5PTwvnuv0dZODy4RPo5Qh0LBiAwTaoLCB45y240VGVeTXurIuH4H5ihLIx0mv+3bYbhNIOgaa+6kbkRdzDBw9oIUEXuX0ihrdsR32kilfMC106eEAkj7Asqc//C/xuuaxJ/jlDHggEITCNRQPgfnq0sk+TBGc0Bhf2xSOzzS/rlTzbDcJpBEDHObr9NWVpg58wqnU57R7LPwcNJ3bsT41tazWQ8KTPOSOHK2pbG1eoGm7CvVulnCBkTDEBgGokCgmvQlGVgUyZFpjBS9f9sTMSadcTucqpBoLJZru7ReS31SxYr+3/+WEJ8p5d8UycrSw/cpUFl60bg2WfFnx9kTDAAgWkkCgj+ilWVgbFUjv6tf3y++ItvJsNwokEQ3KhugAYPCFI2+0dFacS1COI7vRRYvlxd3jbpjhbvcDVTarJCu9LPu4FTBQMQmEaqgOABG6oyMZUKbt4i/uKbyTCcaBC0umhRV2iqVLgmkPR9OzW+paW0S4BC1YwakZbeDZwqGIDANFIFRP3Cp8QzvITVjrPpdJKTDQLfjPvk00+Cqv3DXYjvNFTrnNC3iqefRFU3d474s4OMCwYgMI1UAcEjG6UzvERlpj+WHeRkg6Bh5Qvi6SdRcVMi4js9pbLfqSo1vrZW/LlBxgUDEJhGqoDgWRpqRg0Xz/QSyiBN9Meyg5xsEIQrfeLpJ1GZ7Y/l5PiWlsp5z5VoeFlLc6BZ/LlBxgUDEJhGsoBgj/PiGZ9RsX+s2kbxl95shuFkg4BHiIunI4Niv4Jm+2M5Pb4lxa57VE5DaLX8D84Uf2ZQYoIBCEwjWUCwDzXpjM+ouA+Z9AtvRYbhZIOAfURKpyOj4j6yiO/0Vt2ch8XTkVHppzWE0kMwAIFpJAsIHlChclYQSzPIf6wRf+GtyDCcbBA07VM4K4jFCu3YjfhOcwXXbRRPR4Y0bHBL2B8Sf15QYoIBCEwjXUDUzZsrnwEayiCD4i+8FRmGdHxLS6WPSKtUM36UJc7GEd+yag4eSotmYP+s6eLPCkpcMACBaaQLiNBbb4tngB1mkA/MEH/ZrcowpONbWg1/WymenjpS/aJFiO8MEc8UI52eOhJG/6anYAAC00gXENzRXeVMCpZkkK++Lv6yW5VhSMe3tMI1DZEaXek0FU9N732I+M4Q2f4D95aKlubGg+LPCUpcMACBaexQQASWLpHPCGPp1mGRphzpl92qDMMO8S0t/+yZ8ukqhnxT70Z8Z5AiH7hj7fuBy54YpJ8RlJxgAALT2KGAaPqgUjwjjKX6p54Uf9GtzDDsEN/SCq7dIJ6uYqlxtXWDjRDf9lDgmWfE01UshbbtFH8+UHKCAQhMY5cCwq5TdVnVHGcHwSBoVXPoo5aasbeIp63TNNLT0hw4gPjOMIW9AVt2O6idPMGSwUaQjGAAAtPYpYAIbnhDPENsK989vxd/LlZnGHaJb2kFnn1OPH21Vf2C+YjvDJXfhj4BraxthlIvGIAZTElJyXWkncXFxcfo90/xji0sLCyiY7aQquj47aRLjIZjlwIi0lfm9tvEM0W9gus3iT8XqzMMu8S3tMK+xsj0V9Jp7IRuHhTxU4j4zkyFtu6QT2M68TScGPyR3oIBmMGwUVdQUHA5GXPTOzIAaf/6oqKicl6m4wfQ+g6j4dipgLCTi47aieNNT8VlN8EgOFV2ctHh/+NDiO8MFje18gAf6XQWFQ+8k34mkDnBAHQAZNjdF88ApP3dyeg7Qoudo9vo+CZSgZH/t1MBwV+kNaNHimeOrMY1L4s/DxUZhp3iW1qRmUFs0jcrtOs9xHeGK7h5i3g6i2ikJ1IDLv08IHOCAegADBiA36f9+/XbuBmYtvc28v92KyAaXlwlnkFGZmIIHRZ/FioyDLvFt7Tq5j8mnt78s+5HfDtAkVrAKZPE01tg2TLxZwGZFwzANIaMtK2kA3qRIXdQ++0ZPS4ZA5CbgBMxAA8dak1MdtCBpsMRA0wygwyuXS/+HFSI49lu8S2tZm9di3eEYF/Amwe1hPfsR3w7RKG3tonmbTXs1zQQFn8OkHnxe520AQLSA9VNwHakusI9WCqDrK4ofYMuIUv6GYDU4S13PyCW3jylC6TvH6QWb4V7lVR6qyp33yl9/wAAg7ABSAbe3HjHkLG3gVShHT8wkUEgNiXL6yl9JeUZpMf9efUQ1/ekbx6kll39+p1Nce9NvfHnPlQ1uF836fsHqeWDQTfmUNx/IvCx8e7G3r2/In3/AIAOKCwsvJYMvwau3SMdJQVI1/M+MvL6kZ6KHltQUFDCTcrsBkZr/r1M7sqtwVt207cowzqaYgNwlvR9Axkqy9w/pfj/MpXprcrjKpW+byAD5W1jU/yx8ZnXM+BK6fsGAABDVHtcQ1L4dfz2rquuOkP6noEcVZ7S2SkskJdK3y+QY1qnTp1T2cqBpl8AQNpRXeGel4IMMsw1jtL3CmTh5rHqitJ16tObexc3O0vfL5Blz5Dfnk8fnjXK05undEUn9GsGAKQbf3W5ulR73C+qq4kpPYqmERBll8t1Hn107FaW3ipKa/e5XBdJ3yewB/uGuoq8HnezQgNwI33YnCV9nwAAkBRUYHalQnml9YWx+3Bl+YAfSN8fsBf7Pf0v4Fo6BTUxVahpBm2pLu9/CX3kNir42Fj3fnmfc6TvDwAATKHVBD5oYc3fh1TQl0jfF7An9NFxrpUfHVwYs2EpfV/AnlQOuiGb8rft1n1suBfyh7P0fQEAbEZJScl1pJ3FxcXH2vExmFVUVPQo7ashVdPyaJGLjIG3YmAfytzqTWSMX3o9pXO2ulxflb4XKTTXQux8/F3SbkoDy6WvyaZkUXoZbmo0usf9abXHNX6azk9nKuC5xClet7BnAJ4ZiHRJKsMHiePt2/dM+lCYSR8ex5JNbzsG33R89DVX++gdd0nfD7AOen/n0bvsp98v8/Pzr4hux3sOEoYTTUFBweWUWKa3NQBp3UPb1/Jybm7u+bReZ7dExR3oq8vd4+iL2We8xs/9P8pYn6/0DLii4xAym46ci4NTeb+8/4XsIogMwYPGC2P3ER7AxD7fJK6Z4nc9xXM5L9P7OyADfIM6hn0eVy4ZgktIx42mt91lA77Y4LphAZp8MxMqr6/JycnJpvfYpzcA8Z6DpGnPEKBEtIa2u3XrD7GhmPqr65jWZuGB11d53PPJwNvMjnV1Bt8n3MxLWs0+t9D8dhIjzsXB6XBn+ohronL3063Nde6PdV0KjrKjXR5xSQX3MMmCOBNnB3Ii2ofHUDYGKV3V6fxUfsG1hJH8LeIlYWCfSy++2K83DEBmwrWA0XjGew5M0Z4BSOt7KFFdrTtmFK0vTfW1JUkWj+L0lvX9eie4PYiJZgA2aM2/64zOGw1OI5LeWJ1slN7amx+cm4cQz+kNf/BOi9GVQGsefI9+3yctzM7OxgwzGUgbAxDvOTgdnhVE6+N1QpRQDmq/PaPHGTQAb0sjAxB06jj+CwsLL0/rgAcAAAU5SURBVKTDuvCxtPwT2t5MvyJNlcB62isYtBmCegtdElAMxW10dHkXiusH6Z1+WfSCgBI6MgDxngPDpHsTMLAGit9/UjroL30dwBrQNORsevXqdRFPHyp9HcB60AQMLKO9vmCUeCq0QSCdo4NAMmFuYXASfS1wQUFBMWcaPDBI8pqAtVCcbuB3mZfp/R2IzuGZS3Z29tn0Hp8XXaf4nkB5+CbBSwKK0BuA2jrec5AYVNhfq/UBO8JfiqQA6Xptd2fNDUwtyUsJaozoxQLL4SZ9ramf+wDuRO1f5kEGQQl3BWD3EFqzED7iMpS8vLx8zaVTtA/gKor/XOnrAtZBcfsEl9kUt8f5g51dtPF2vOcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApC+aA/htRo7VHMg/n0w4dO4v2I9ZMucCAAAAAAAL0QzArUaO1QzA55IJRzMAQ8mcCwAAAAAALAQGIAAAAABAgpBBNJGnVCTj5l/0W0OGjlu3bxJPrUj7DtLvi3l5ed+M7uO5PbVz36Hlf9Pvyl69en2Dzn+ap2nkqb1o+dLo8fn5+T1o2wraFybVszEW65rouJfomCd11zGX9FqMY08xAGl9Dv8/3w9pFy3/PLpPMwBfoO3Ltfv9QL+/W7duX9NNXRXiqSVpc1ftXBiAAAAAAEh/tPk4/1NYWFjE62ykkRH3bV6m7TeTweOjY4rJ+DmT1hfQ+pvRc9kA5PmY6fiLcnNzz9fm9Kyk435Nu7Pod57OaOP17aTptHwGn8OGI/3viPauq2fPnhfQ/kbafyP956/YaORra+/YtgYgLQ/m66HFzrQ8jtRM4Z3F+9gA5DlJadsQ3k/LHlr+mO7xPO3cF0iLevTocQ4d+3Xa/yqtz9DOhQEIAAAAgPSHDJoCNgDpt3/USIpC29eSxkbXu3fvfi4bT3l5efnauWwAenTHz6P1V6LrZDD9mLYd0I79ESmo/3/aP5S2rY91bWxI8vlcG0fH9otzD3GbgGn/R3T+lVqYbADubBPOu2wQ0r7ufH9s/OnO/RnXgGrnwgAEAAAAQGZAhs1AMnI2cbMtaTXXCvJ2Wv6wreHFo2Bp/zXasp/299Htm03nLNatf5fWP9XCcNH6Z2yMsbjWjXSElvfEubTOWq3i/njX304T8J187VoYrM+1WskTTcBtzl9F2+6i+/oh/X4RvUbtOo/wc9HOhQEIAAAAgMyCawC1ZtvNvB6rBpCO68XriRiA9Hs1Nycncj303/eyexeuoaPlO2IdpzcAucaOdIiOv0y3/6PodcaoAXyHawC5iZl+j9GmLjGuBwYgAAAAANIfru0j/ZL7+NFqF/qdRUbOBt7HfQC5+ZP7ALJxSNvnk96KnmvQAPyvttpZ6wM4NTs7+2xaz+J+h/oBGHo0g/EwNzfzQBKuyaPjv9PesXoDkI7py7WU2mCVrrR9Ctc8tjEAj5MGafdbzv/Ng1e0cLkP4ILoOv1fDh3zG+1cGIAAAAAASH/IuLucDJ63tVG73Oy5LtoETGSR0TOZa+64Vo1H5ubk5GRHz+XtRmsAGTKmLuQRwtwXUGuafUc/4jgK98GjfV427KLbuCZSay7u2vb4Nk3A3Gy8ULsfDmei/jq1JuCVtG2ZNgp4Lxt20f/iWk6tL2Od1vy7l5bHaOfCAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQ4f+tLNGFZ9oTjQAAAABJRU5ErkJggg==\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"with replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=True) as figure:\n",
|
|
" figure.plot(np.sin, linewidth=20)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"scrolled": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"replot.plot([range(10), (np.sin, (-5, 5)), np.cos, (lambda x: np.sin(x) + 4, (-10, 10), {\"linewidth\": 10}), (lambda x: np.sin(x) - 4, {\"linewidth\": 10}), ([-i for i in range(5)], {\"linewidth\": 10})],\n",
|
|
" xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=\"best\",\n",
|
|
" palette=\"dark\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 19,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"replot.plot([range(10), (np.sin, (-5, 5)), np.cos, (lambda x: np.sin(x) + 4, (-10, 10), {\"linewidth\": 10}), (lambda x: np.sin(x) - 4, {\"linewidth\": 10}), ([-i for i in range(5)], {\"linewidth\": 10})],\n",
|
|
" xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=\"best\",\n",
|
|
" palette=replot.sns.color_palette(\"husl\", 2))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"ename": "InvalidParameterError",
|
|
"evalue": "Second parameter in plot command should be a tuple specifying plotting interval.",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[1;31mInvalidParameterError\u001b[0m Traceback (most recent call last)",
|
|
"\u001b[1;32m<ipython-input-8-123737853af4>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mwith\u001b[0m \u001b[0mreplot\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mFigure\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mfigure\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mfigure\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msin\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
|
|
"\u001b[1;32m/home/phyks/Code/replot/replot/__init__.py\u001b[0m in \u001b[0;36mplot\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 111\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mhasattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m\"__call__\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 112\u001b[0m \u001b[1;31m# We want to plot a function\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 113\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_plot_function\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 114\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 115\u001b[0m \u001b[1;31m# Else, it is a point series, and we just have to store it for\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
"\u001b[1;32m/home/phyks/Code/replot/replot/__init__.py\u001b[0m in \u001b[0;36m_plot_function\u001b[1;34m(self, data, *args, **kwargs)\u001b[0m\n\u001b[0;32m 145\u001b[0m raise exc.InvalidParameterError(\n\u001b[0;32m 146\u001b[0m \u001b[1;34m\"Second parameter in plot command should be a tuple \"\u001b[0m \u001b[1;33m+\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 147\u001b[1;33m \"specifying plotting interval.\")\n\u001b[0m\u001b[0;32m 148\u001b[0m \u001b[0my_values\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[0mdata\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mx_values\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 149\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mplots\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx_values\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my_values\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0margs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
"\u001b[1;31mInvalidParameterError\u001b[0m: Second parameter in plot command should be a tuple specifying plotting interval."
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.sin, None)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function() {\n",
|
|
" if (typeof(WebSocket) !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert('Your browser does not have WebSocket support.' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.');\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = (this.ws.binaryType != undefined);\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById(\"mpl-warnings\");\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent = (\n",
|
|
" \"This browser does not support binary websocket messages. \" +\n",
|
|
" \"Performance may be slow.\");\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = $('<div/>');\n",
|
|
" this._root_extra_style(this.root)\n",
|
|
" this.root.attr('style', 'display: inline-block');\n",
|
|
"\n",
|
|
" $(parent_element).append(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
|
|
" fig.send_message(\"send_image_mode\", {});\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var rubberband = $('<canvas/>');\n",
|
|
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
|
|
"\n",
|
|
" var pass_mouse_events = true;\n",
|
|
"\n",
|
|
" canvas_div.resizable({\n",
|
|
" start: function(event, ui) {\n",
|
|
" pass_mouse_events = false;\n",
|
|
" },\n",
|
|
" resize: function(event, ui) {\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" stop: function(event, ui) {\n",
|
|
" pass_mouse_events = true;\n",
|
|
" fig.request_resize(ui.size.width, ui.size.height);\n",
|
|
" },\n",
|
|
" });\n",
|
|
"\n",
|
|
" function mouse_event_fn(event) {\n",
|
|
" if (pass_mouse_events)\n",
|
|
" return fig.mouse_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband.mousedown('button_press', mouse_event_fn);\n",
|
|
" rubberband.mouseup('button_release', mouse_event_fn);\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
|
|
"\n",
|
|
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
|
|
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
|
|
"\n",
|
|
" canvas_div.on(\"wheel\", function (event) {\n",
|
|
" event = event.originalEvent;\n",
|
|
" event['data'] = 'scroll'\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" mouse_event_fn(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.append(canvas);\n",
|
|
" canvas_div.append(rubberband);\n",
|
|
"\n",
|
|
" this.rubberband = rubberband;\n",
|
|
" this.rubberband_canvas = rubberband[0];\n",
|
|
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
|
|
" this.rubberband_context.strokeStyle = \"#000000\";\n",
|
|
"\n",
|
|
" this._resize_canvas = function(width, height) {\n",
|
|
" // Keep the size of the canvas, canvas container, and rubber band\n",
|
|
" // canvas in synch.\n",
|
|
" canvas_div.css('width', width)\n",
|
|
" canvas_div.css('height', height)\n",
|
|
"\n",
|
|
" canvas.attr('width', width);\n",
|
|
" canvas.attr('height', height);\n",
|
|
"\n",
|
|
" rubberband.attr('width', width);\n",
|
|
" rubberband.attr('height', height);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
|
|
" // upon first draw.\n",
|
|
" this._resize_canvas(600, 600);\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus () {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" // put a spacer in here.\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" var button = $('<button/>');\n",
|
|
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
|
|
" 'ui-button-icon-only');\n",
|
|
" button.attr('role', 'button');\n",
|
|
" button.attr('aria-disabled', 'false');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
"\n",
|
|
" var icon_img = $('<span/>');\n",
|
|
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
|
|
" icon_img.addClass(image);\n",
|
|
" icon_img.addClass('ui-corner-all');\n",
|
|
"\n",
|
|
" var tooltip_span = $('<span/>');\n",
|
|
" tooltip_span.addClass('ui-button-text');\n",
|
|
" tooltip_span.html(tooltip);\n",
|
|
"\n",
|
|
" button.append(icon_img);\n",
|
|
" button.append(tooltip_span);\n",
|
|
"\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker_span = $('<span/>');\n",
|
|
"\n",
|
|
" var fmt_picker = $('<select/>');\n",
|
|
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
|
|
" fmt_picker_span.append(fmt_picker);\n",
|
|
" nav_element.append(fmt_picker_span);\n",
|
|
" this.format_dropdown = fmt_picker[0];\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = $(\n",
|
|
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
|
|
" fmt_picker.append(option)\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add hover states to the ui-buttons\n",
|
|
" $( \".ui-button\" ).hover(\n",
|
|
" function() { $(this).addClass(\"ui-state-hover\");},\n",
|
|
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
|
|
" );\n",
|
|
"\n",
|
|
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function(type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function() {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1]);\n",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
|
|
" var x0 = msg['x0'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch(cursor)\n",
|
|
" {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = \"image/png\";\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data);\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig[\"handle_\" + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"}\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function(e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e)\n",
|
|
" e = window.event;\n",
|
|
" if (e.target)\n",
|
|
" targ = e.target;\n",
|
|
" else if (e.srcElement)\n",
|
|
" targ = e.srcElement;\n",
|
|
" if (targ.nodeType == 3) // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
"\n",
|
|
" // jQuery normalizes the pageX and pageY\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" // offset() returns the position of the element relative to the document\n",
|
|
" var x = e.pageX - $(targ).offset().left;\n",
|
|
" var y = e.pageY - $(targ).offset().top;\n",
|
|
"\n",
|
|
" return {\"x\": x, \"y\": y};\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys (original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object')\n",
|
|
" obj[key] = original[key]\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event)\n",
|
|
"\n",
|
|
" if (name === 'button_press')\n",
|
|
" {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x;\n",
|
|
" var y = canvas_pos.y;\n",
|
|
"\n",
|
|
" this.send_message(name, {x: x, y: y, button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function(event, name) {\n",
|
|
"\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name == 'key_press')\n",
|
|
" {\n",
|
|
" if (event.which === this._key)\n",
|
|
" return;\n",
|
|
" else\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" if (name == 'key_release')\n",
|
|
" this._key = null;\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which != 17)\n",
|
|
" value += \"ctrl+\";\n",
|
|
" if (event.altKey && event.which != 18)\n",
|
|
" value += \"alt+\";\n",
|
|
" if (event.shiftKey && event.which != 16)\n",
|
|
" value += \"shift+\";\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, {key: value,\n",
|
|
" guiEvent: simpleKeys(event)});\n",
|
|
" return false;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
|
|
" if (name == 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message(\"toolbar_button\", {name: name});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" fig.root.unbind('remove')\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable()\n",
|
|
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function() {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message(\"ack\", {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var nav_element = $('<div/>')\n",
|
|
" nav_element.attr('style', 'width: 100%');\n",
|
|
" this.root.append(nav_element);\n",
|
|
"\n",
|
|
" // Define a callback function for later on.\n",
|
|
" function toolbar_event(event) {\n",
|
|
" return fig.toolbar_button_onclick(event['data']);\n",
|
|
" }\n",
|
|
" function toolbar_mouse_event(event) {\n",
|
|
" return fig.toolbar_button_onmouseover(event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for(var toolbar_ind in mpl.toolbar_items){\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) { continue; };\n",
|
|
"\n",
|
|
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
|
|
" button.click(method_name, toolbar_event);\n",
|
|
" button.mouseover(tooltip, toolbar_mouse_event);\n",
|
|
" nav_element.append(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
|
|
" nav_element.append(status_bar);\n",
|
|
" this.message = status_bar[0];\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
|
|
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
|
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
|
|
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
|
|
" buttongrp.append(button);\n",
|
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
|
|
" titlebar.prepend(buttongrp);\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(el){\n",
|
|
" var fig = this\n",
|
|
" el.on(\"remove\", function(){\n",
|
|
"\tfig.close_ws(fig, {});\n",
|
|
" });\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.attr('tabindex', 0)\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
" else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager)\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which == 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" event.shiftKey = false;\n",
|
|
" // Send a \"J\" for go to next cell\n",
|
|
" event.which = 74;\n",
|
|
" event.keyCode = 74;\n",
|
|
" manager.command_mode();\n",
|
|
" manager.handle_keydown(event);\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function(html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i=0; i<ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code'){\n",
|
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] == html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"}\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel != null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"ename": "InvalidParameterError",
|
|
"evalue": "You should pass at least one argument to this function.",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[1;31mInvalidParameterError\u001b[0m Traceback (most recent call last)",
|
|
"\u001b[1;32m<ipython-input-9-04fab9ca003f>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mwith\u001b[0m \u001b[0mreplot\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mFigure\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mfigure\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mfigure\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
|
|
"\u001b[1;32m/home/phyks/Code/replot/replot/__init__.py\u001b[0m in \u001b[0;36mplot\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 107\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 108\u001b[0m raise exc.InvalidParameterError(\n\u001b[1;32m--> 109\u001b[1;33m \"You should pass at least one argument to this function.\")\n\u001b[0m\u001b[0;32m 110\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 111\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mhasattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m\"__call__\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
"\u001b[1;31mInvalidParameterError\u001b[0m: You should pass at least one argument to this function."
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "physique",
|
|
"language": "python",
|
|
"name": "physique"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.5.1"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 0
|
|
}
|