Phyks (Lucas Verney)
264253ed3e
List of tuples input is now considered as being a list of (X, Y) coordinates contrary to standard matplotlib API which considers it is a list of ordinates for two graphs.
31138 lines
2.9 MiB
31138 lines
2.9 MiB
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Replot\n",
|
|
"======\n",
|
|
"\n",
|
|
"This is some basic Jupyter notebook to show you the features of [replot](https://github.com/Phyks/replot). It gives you usage examples, and is used by me as a visual test suite to check I did not break anything between updates.\n",
|
|
"\n",
|
|
"For detailed documentations, please refer to the module documentation."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Let's go!\n",
|
|
"\n",
|
|
"First import the required modules. Note that importing `replot` will not have any side effect and that if you previously imported `matplotlib` it will be left untouched."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import replot\n",
|
|
"\n",
|
|
"%matplotlib notebook"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Also import numpy as it will be useful…\n",
|
|
"import numpy as np\n",
|
|
"\n",
|
|
"# and add some black magic for easy reloading of the module before executing any cell (just here to ease testing)\n",
|
|
"%load_ext autoreload\n",
|
|
"%autoreload 2\n",
|
|
"\n",
|
|
"# ignore matplotlib warnings about too many figures in the notebook\n",
|
|
"import matplotlib as mpl\n",
|
|
"mpl.rcParams[\"figure.max_open_warning\"] = 40"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Basic plotting\n",
|
|
"\n",
|
|
"Let's start by doing some basic plotting."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"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": [
|
|
"# Let's plot a basic data series, as we would do with matplotlib\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" x = range(10)\n",
|
|
" figure.plot(x)"
|
|
]
|
|
},
|
|
{
|
|
"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": [
|
|
"# Or a (X, Y) point series, as we would do with matplotlib\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" x = range(10)\n",
|
|
" y = [i**2 for i in x]\n",
|
|
" figure.plot(x, y)"
|
|
]
|
|
},
|
|
{
|
|
"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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ceXabfvqZwfVY3ftcJMPBRDWjPNw4KYX3MQyUQKvHjoxun74pF35s712uEmHAghrxnk4cNMLboKJorda/qL41UXQqfxZXzvcZEMBhDXjPBy46QU3wVAApYObZiiAsGachwM3veAmFl4Clg9umqEAwppxHg7c9IKbUPgQiEVw0wwFENaM83DgphfcdMLXwHgEN81QAGHNOA8HbnrBTSt8EbR+cNMMBRDWjPNw4KYX3HTj7IebZtzdsvsDiOM8HLjpBTfdOPvhphl3t+z+AOI4DwduesFNN85+uGnG3S27P4A4zsOBm15w042zH26acXfL7g8gjvNw4KYX3HTj7IebZtzdsvsDiOM8HLjpBTfdOPvhphl3t+z+AOI4DwduesFNN85+uGnG3S27P4A4zsOBm15w042zH26acXfL7g8gjvNw4KYX3HTj7IebZtzdsvsDiOM8HLjpBTfdOPvhphl3t+z+AOI4DwduesFNN85+uGnG3S27P8CLQFVVH4jsGwwGf7ewsLB9vO9AbO+MHIn1uabHdh4O3PSCm26c/XDTjLtbey0DppJ+v//WyGvH62+LwvflKHw7hsPhqbIvlrOx70zT4zsPB256wU03zn64acbdra2eAVNKlLsPR+H787Iey1dH4ftW5LHyjODEz1xsenzn4cBNL7jpxtkPN824u7XRMWC6eaDX6/1MWRm/DPynkc9F9tQ/EOtLnU5nS5ODl+FYWbl5MzmlOOGmF9x04+yHm2bc3doqGTDlzMzMPBRF7x+3bt36suFw+ESUwV31Y7F9udvtbm5y3BEAAADI0V7DgGnm/ih/j2/btu3lZSMK38EogHvrB2P7UtMDl5vI9bcj3PSCm26c/XDTjLtbG+UCppwoeO9fWFjYWtbLJ397vd7DsTxRtmM9Vgdnmx67DEe5mbLfz8B7P3DDTTvOfrhpxt2trY4BU0r55G8UwB9GyVse58myv6qqo7F/d2QxfqZqenzn4cBNL7jpxtkPN824u7XXNGBD4jwcuOkFN904++GmGXe37P4A4jgPB256wU03zn64acbdLbs/gDjOw4GbXnDTjbMfbppxd8vuDyCO83DgphfcdOPsh5tm3N2y+wOI4zwcuOkFN904++GmGXe37P4A4jgPB256wU03zn64acbdLbs/gDjOw4GbXtzcnj13frR8Yfn5brFv9bEpOEeuHW646YUCCGvGeThw04uTWyl41/cfG11ZPL1a+G65LS2v7iuPOZVAp2uHm0fc3bL7A4jjPBy46cXK7cJzRa8sS/G7ceXabfvqZwcdYnXtcLOIu1t2fwBxnIcDN73YuU2UwKuHToyuHz5pWf4srx1u8nF3y+4PII7zcOCmF0u3KHqr5S+KX10E3X1/cz4AAAwwSURBVMqf7bXDTTrubtn9AcRxHg7c9GLpRgGUD26acXfL7g8gjvNw4KYXOzdeArYIbppxd8vuDyCO83DgphcrNz4EYhPcNOPult0fQBzn4cBNL05ufA2MT3DTjLtbdn8AcZyHAze9uLnxRdAewU0z7m7Z/QHEcR4O3PSCm26c/XDTjLtbdn8AcZyHAze94KYbZz/cNOPult0fQBzn4cBNL7jpxtkPN824u2X3BxDHeThw0wtuunH2w00z7m7Z/QHEcR4O3PSCm26c/XDTjLtbdn8AcZyHAze94KYbZz/cNOPult0fQBzn4cBNL7jpxtkPN824u2X3BxDHeThw0wtuunH2w00z7m7Z/QHEcR4O3PSCm26c/XDTjLtbdn8AcZyHAze94KYbZz/cNOPult0fQBzn4cBNL7jpxtkPN824u2X3BxDHeThw0wtuunH2w00z7m7Z/QHEcR4O3PSCm26c/XDTjLtbdn8AcZyHAze94KYbZz/cNOPult0fQBzn4cBNL7jpxtkPN824u2X3B3iRGA6Hf9jr9d5Ub1dVdWAwGOyMHIn1uabHdR4O3PSCm26c/XDTjLtbO+0CpplNUfA+GAXw36LsvbnsiO0dsX2qrMdyNvafaXpw5+HATS+46cbZDzfNuLu1VTJgyomS92RdAKP0HYwSuG/isYtNj+s8HLjpBTfdOPvhphl3tza6BQgwWQBjeTyyZ+KxpU6ns6XJcctwrKzcvJmcUpxw08iz586Pnllafr5b7Ft9bArOkeu2sf1w04y7W1v9AqacO54BfKKqql31Y7F9udvtbm5y3BFAIj/5+lOj6/uPjX70Z0+Obly5dmt/WS/7ymPlZwAA4Hba6hcw5dzlJeC99WOxfanpcctN5PrbEW4CWVoeXVk8vVr0ynLl4vJq+ZvcVz87qB6r67bB/HDTjLtbG90CBLijAD5SngUs671eL3YPzjY9bhmOcjNlv5+B935sYLcLz5XAq4dOjK4fPnmr/JXH0s+P67bh/XDTjLtbW/0Cppiqqj4QJe87kb+J9beM9x2NErg7stjv96umx3YeDtyEEkVvtfxF8auLoFP5s71uG8QPN824u7VWMmBj4jwcuAmFAigfZz/cNOPult0fQBzn4cBNJLwEbBFnP9w04+6W3R9AHOfhwE0gF5af94GPOz8E4lICra7bBvPDTTPubtn9AcRxHg7cpj/le/4mi94tt4lPB5efyT5PrtvG9sNNM+5u2f0BxHEeDtw0slrwxs/y3eZ2Ydmm/Dlet43kh5tm3N2y+wOI4zwcuOkFN904++GmGXe37P4A4jgPB256wU03zn64acbdLbs/gDjOw4GbXnDTjbMfbppxd8vuDyCO83DgphfcdOPsh5tm3N2y+wOI4zwcuOkFN904++GmGXe37P4A4jgPB256wU03zn64acbdLbs/gDjOw4GbXnDTjbMfbppxd8vuDyCO83DgphfcdOPsh5tm3N2y+wOI4zwcuOkFN904++GmGXe37P4A4jgPh5Mb/7cM/Ti7ufvhphl3t+z+AOI4D4eLG/+/XI84u7n74aYZd7fs/gDiOA+HjduF54peWZbid+PKtdv21c8Oqsfqum0gN3c/3DTj7pbdH0Ac5+GwcpsogVcPnRhdP3zSrvxZXrcN4ubuh5tm3N2y+wOI4zwcdm5R9FbLXxS/ugg6lT/b67YB3Nz9cNOMu1t2fwBxnIfDzo0CKB1nN3c/3DTj7pbdH0Ac5+GwcuMlYPk4u7n74aYZd7fs/gDiOA+HjRsfArGIs5u7H26acXfL7g8gjvNwuLjxNTAecXZz98NNM+5u2f0BxHEeDic3vghaP85u7n64acbdLbs/gDjOw4GbXnDTjbMfbppxd8vuDyCO83DgphfcdOPsh5tm3N2y+wOI4zQcvEyqH9x04+yHm2bc3bL7A4jjMhx8UMIjuOnG2Q83zbi7ZfcHEMdmOPiqFIvgphtnP9w04+6W3R9AHKvh4MuS5YObbpz9cNOMu1t2fwAxrn5k8dEf/MGhV9Tbdu+T43+XJh3cdOPsh5tm3N0yuwQkU1XVgcFgsDNyJNbnXujnS/krpeja/sVv1iXQ7n1yFEDp4KYbZz/cNOPutv4tA6aSKHw7hsPhqbIey9kogWde6M+U0lfK32QJtHqfHC8Bywc33Tj74aYZd7f1bxowlUTpOxglcF+9HQXw4r38udtL4LGnbUoSHwKxCG66cfbDTTPubuvXMGCqicJ3PLJnYnup0+lsuZc/e7MERvmbeJm0FKZyQ6lm8mtgisvKys3BX7l4+8vb2efZRm65reSfC264bQQ/3DTj7rZ+DQOmmuFw+ERVVbsmti93u93N9/Jn7yyAZX3ygyGq3PkBl5qyrzyWcU4AAAAArTF+CXjvxPale/lzd74EXBfByQ+GAAAAAMAUEoXvkfIsYFnv9XqD4OwL/Zm7fQjkbvvW/+wBAAAAoBFVVR2NErg7stjv96sX+vm7fQ1MYbIE8lIpAAAAgBm8Tw4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgTaqqOjAYDHZGjsT6XPb5rAfD4fAPe73em7LPo23ien0gsi+u3d8tLCxszz6fNgmvd4bX2yOfi+v3G9nnsx4UN7eZi2v1+lg80Ol0ttzL/5ZSie3bty/ENXs8vN4R121X9vm0xXwQ1+0zW7dufVn2uawHcc1+rVyzcHx/LF+bfT5tEm6PRt4b+VS4/UL2+YAQ8ZfYjhiKU2U9lrNxE53JPqeW2RSOHwy3fwu3N2efTJvEsL+1/ssslm8Lvy9nn1NblH9o45p9q6yH26+X65d9Tm0T9+Ub4pr9V/xisi37XNoknJ6K67US+UK3253JPp82CaevlmJbvMLzn7LPpy3iXnxL+FwPv+9Hno7178V9+XD2ebXBzMzMQ+HzoXq7FPjM82mTuG5vDJ+TZb3cl7H+99nnBELEsB8szyDV23EDXcw8n/UivJ50K4Dh8+G4dn9e1mP56tj+j+xzapNt27a9vCzLb7bh98fZ59My5ReT3y2Fwq0AhtN7ss9hPSglqZTaiV2b0k6mZcoz7feNfUphCtd3J59Sm2yK6/btmLPXzc7O/lx5QiD7hNoirtvHw+2xie3vZp4PiBE3zPHInontpfKbROY5rQeOBTB4IP5S+5myMn4Z+E+zT6hlXlpetgmv0/cZ/WNbiOv1e7F4MNy+ZlgAF8uz0+Ufpvn5+V/MPp+2CJ+PlWfZ49r9diz/KBx/Ofuc1oNSKmJxf/Z5tMn475FrkS/F5kuzz6ctxm8BuvXLcdyj/1MKfOY5gRBxwzwx+V6W2L7c7XY3Z57TemBaAFcZv8Txj67v34l7cnfki9nn0RYxb68Zv0/uPscCeN+4PIzvy/PZJ9MW4fKJcr3Gmy8pL3WnntA6EE6/Gffn72SfR5vELyE/PX7f5i/F8huRv8w+p7YIp5+vfcoznPH3yv86/vsN68T4JeC9E9uXMs9nvTAugPeXv9zql0sdib/YQnFww+X9ZOUl0nF+P/KfMX8fLS9NZZ9XG5T3oobTZ8ebpSRdTT2hFim/iMS1+tt62/HVknD8ShSmV2afR5uUD36U97qPN1efdXf6+7IUv3D6rfKezXD91+zzASHihnmkPAtY1sf/0J7NPqf1wLUAlr/cFhYWtpb18knu7PNpi+IVPv9Q1st1K29Kj9WXJJ9W67g9AxgF8FfqDw/Effmq8Pvn7HNqi/EHP86NNx+I9W+mnlD7lPfK/TiWD2afSJvEdXpfeP3qxHb5EIjFy8BRbPvh8xdlvcxdbO/PPicQI26ao+OX2RbdvrahUN4nEUPyncjflDdyZ59PW4yfbflheC2P82T2ObVFKbXlqw3G9+Wp8ltu9jm1Tfmam/KMe3nGbG5u7hXZ59MW5f2o5VWFuH6HXZ61rRl/3caHwu+T5Zfn7PNpk/n5+Z8Np//OPo914MHyVWflgy3l3nT5dHOhvNxb7sXIu4pj9vkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAePN/qFSLrlicHTQAAAAASUVORK5CYII=\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"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+AAAgAElEQVR4nO2dbYhdeX3Hd901LTFLq53byJ1pMnPvudfiA6KwC2lFpLRQ+yixxAQfqmnsVkQlisaN2MZkCZNSX5i6Sds0bPui9EVJ1UhfpIj2jQTb4lYRC33TzcTkxezURZsHUcjt7z+5J3uTDWx65sz+7vc7nw989zzcyeF8OOeXfOc+7X33AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwIZjMBg8Gnlv5FNVVc2VfbE8ENs7I0fqfQAAAABgQJS7N0bJO1nWO53Ollj/+9i3Yzgcnir7Yjkb+87kniUAAAAAtEaUu49HyXtsYvu7ZTtK4L6JfRdzzg4AAAAAWieK3gcif1xvR/n7nyh8pyN76n2xvlSeHcw5QwAAAABolX6///NR8P6yrPd6vddFAbwS+esohbvqn4nty91ud3OT49+4cWMEAAAAWrTVM2CKKcUvSuBvxfLhKHv/On4JeG/9eGxfanrschOtrPxw9MwzXilOuOkFN904++GmGXe3dhoGTC1R9PpR/v6irJcCGNv7yzL2nRjvi9XB2abHL8NRbqblZa8UJ9z0gptunP1w04y7W1s9A6aU8tJulL5PRt5Vvvql3h/rR4fD4e7IYr/fr5oe33k4cNMLbrpx9sNNM+5u7bQM2LA4DwduesFNN85+uGnG3S27P4A4zsOBm15w042zH26acXfL7g8gjvNw4KYX3HTj7IebZtzdsvsDiOM8HLjpBTfdOPvhphl3t+z+AOI4DwduesFNN85+uGnG3S27P4A4zsOBm15w042zH26acXfL7g8gjvNw4KYX3HTj7IebZtzdsvsDiOM8HLjpBTfdOPvhphl3t+z+AOI4DwduesFNN85+uGnG3S27P4A4zsOBm15w042zH26acXfL7g8gjvNw4KYX3HTj7IebZtzdsvsDiOM8HLjpBTfdOPvhphl3t+z+AOI4DwduesFNN85+uGnG3S27P4A4zsOBm15w042zH26acXfL7g8gjvNw4KYX3HTj7IebZtzdsvsDiOM8HLjpBTfdOPvhphl3t+z+AOI4DwduesFNN85+uGnG3S27P4A4zsOBm15w042zH26acXfL7g8gjvNw4KYX3HTj7IebZtzdsvsDiOM8HLjpBTfdOPvhphl3t+z+AOI4DwduesFNN85+uGnG3S27P4A4zsOBm15w042zH26acXfL7g8gjvNw4KYX3HTj7IebZtzdsvsDiOM8HLjpBTfdOPvhphl3t+z+AOI4DwduesFNN85+uGnG3S27P4A4zsOBm15w042zH26acXfL7g8gjvNw4KYX3HTj7IebZtzcnj13frR8YfmWW/3v+A/+4NArrn5k8dHMLgGCOA2H8+Djph9nN3c/3DTj5FbK3/X9x0ZXFk+vlsC6AJbyd23/4jfLY5RA+H/hMhzOg4+bR5zd3P1w04yVW5S+Uv7qEvjM0vJosvyVZdnO7hQghM1wOA8+bhZxdnP3w00zdm4TJfDqoRNR+o49TfmDxlgNh/Pg4yYfZzd3P9w0Y+kWJbCUv1L8bpa/Y09T/owZDAa/1u/33zEcDt9fVdVryr5YHoj9OyNHYn2u6bHthsN58HGTjrObux9umrF0owBuHGZmZh6KkvehejvWH4/CtyPK4KmyHcvZ2Hem6fHthsN58HGTjrObux9umrFz4yXgDcemKHnf7vV6r5udnf25KH8fjO2DsdxX/0AUwItND241HM6Dj5t8nN3c/XDTjJUbHwLZmJSXf6PkXYt8KTY3xfJ4ZE/9eKwvdTqdLU2OXYZjZeXmoDilOOGmF9x04+yHm2ac3Ca/BqaUv+JU/g3na2CMmZ+f/+nysm+UwF+K5Teqqvqr4XD4+Vjuqn8mti93u93NTY4/AgAAgKnnJ19/anTjyrVb2/W/43wRtCnjD37sGG8+ECXwX2LfY7Fv78TPXGp6/HITOfx25PybH24ecXZz98NNM+5uay4YMN1E4XtfFLxfndh+vNfrPRzLE2U71mN1cLbp8ctwlJsp/f0NvPcDN9yk4+yHm2bc3droGDDdPFi+8iXy7vLBj1L+ys5YPxrFcHdksd/vV00P7jwcuOkFN904++GmGXe39moGbEichwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0B1pn5YDgcfmbr1q0vm9xfVdWBwWCwM3Ik1ueaHt95OHDTC266cfbDTTPubmtvGDDVRLl7S5S861ECvx95Ota/F3lzrJ8qj8dyNrbPND2+83DgphfcdOPsh5tm3N3aaxowlUS5e3ssNpX1mZmZh6IQvjtK38FY7pv4mYtNj+88HLjpBTfdOPvhphl3txYqBqgQRe/jsbg/lscjeyb2L3U6nS1NjlmGY2Xl5s3klOKEm15w042zH26acXdrrVzAdBMl7zerqvqdsj4cDp+I9V31Y7F9udvtbm5y3BEAAADI0Va/gCknSt5X5ufnXzleLy8B75147FLT45abyPW3I9z0gptunP1w04y7WxvdAqafTVHyfhzLB8tGrD9SngUs671ebxCcbXrgMhzlZsp+PwPv/cANN+04++GmGXe3lvoFTDPz8/M/G4Xvvyf3VVV1NPbtjiz2+/2q6bGdhwM3veCmG2c/3DTj7rb2dgEbGufhwE0vuOnG2Q83zbi7ZfcHEMd5OHDTC266cfbDTTPubtn9AcRxHg7c9IKbbpz9cNOMu1t2fwBxnIcDN73gphtnP9w04+6W3R9AHOfhwE0vuOnG2Q83zbi7ZfcHEMd5OHDTC266cfbDTTPubtn9AcRxHg7c9IKbbpz9cNOMu1t2fwBxnIcDN73gphtnP9w04+6W3R9AHOfhwE0vuOnG2Q83zbi7ZfcHEMd5OHDTC266cfbDTTPubtn9AcRxHg7c9IKbbpz9cNOMu1t2fwBxnIcDN73gphtnP9w04+6W3R9AHOfhwE0vuOnG2Q83zbi7ZfcHEMd5OHDTC266cfbDTTPubtn9AcRxHg7c9IKbbpz9cNOMu1t2fwBxnIcDN73gphtnP9x08uy586PlC8vPd4t9q49NwTm2dd2y+wOI4zT4dw4HbnrBTTfOfrhppBS86/uPja4snl4tfLfclpZX95XHXEogBRDWjMvg3204cNMLbrpx9sNNJBeeK3plWYrfjSvXbttXPzuoHgogrBmbwb/LcOCmF9x04+yHm1AmSuDVQydG1w+ftCt/9XXL7g8gjtXg3zEcuOkFN904++Emlih6q+Uvil9dBJ3KX33dsvsDiGM3+BPDgZtecNONsx9uYqEAArwwdoM/MRy46QU33Tj74SYUXgIGuDesBv+O4cBNL7jpxtkPN5HwIRCAe8dm8O8yHLjpBTfdOPvhphG+Bgbg/4HL4N9tOHDTC266cfbDTSd8ETTAPeI0+HcOB256wU03zn64acbdLbs/gDjOw4GbXnDTjbMfbppxd8vuDyCO83DgphfcdOPsh5tm3N2y+wOI4zwcuOkFN904++GmGXe37P4A4jgPB256wU03zn64acbdLbs/gDjOw4GbXnDTjbMfbppxd8vuD/AisH379oXBYPB4v99/R1VVu8q+WB6IfTsjR2J9rumxnYcDN73gphtnP9w04+7WXsuAqWU4HH610+ls6Xa7M1H4/ikK347Yd2r82GzsO9P02M7DgZtecNONsx9umnF3a69lwFQSZe8tUfK+MLFrU2wfjP376h1RAC82Pb7zcOCmF9x04+yHm2bc3dZULmD6ibL3sSh4X47C99uxfLTf7/9yLI9H9tQ/E+tL5RnCJscvw7GycvNmckpxwk0vuOnG2Q83zbi7tdc0YCqJcveJyNfGmy+J9aeiFH6+fi9gIbYvd7vdzU2OPwIAAAA5WikZML1EudsdZe9v6+3ybF/k07Fv78TPXGp6/HITuf52hJtecNONsx9umnF3W2u/gCln/MGPc+PNB2L9m71e7+FYnig7Yj1WB2ebHr8MR7mZst/PwHs/cMNNO85+uGnG3a2VkgHTTRS890Y+VFXVJ4fD4SNlX6wfLc8ORhb7/X7V9NjOw4GbXnDTjbMfbppxd2uvZcCGxHk4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH+BFYDgcvj4WD3Q6nS1VVfXLvlgeGAwGOyNHYn2u6bGdhwM3veCmG2c/3DTj7tZayYDpJUreU1ECVyJf6Ha7M1H4dsT6qfJYLGfj8TNNj+08HLjpBTfdOPvhphl3t/ZaBkwtUfLec8f2wSiB++rtKIAXmx7beThw0wtuunH2w00z7m5r6RUgQhS+xX6//9YofZ+cn5//xSh8xyN76sdjfam8PNzk2GU4VlZu3kxOKU646QU33Tj7ubk9e+786Jml5ee7xb7Vx6bgHLluL+zWXsuAaeb+8p+ZmZmHouydj0L4+SiDu+oHY/tyt9vd3OTAIwAA2DD85OtPja7vPzb60Z89Obpx5dqt/WW97CuPlZ+B6aetggFTSr/ff1sUvM+ON18SBfBabD8WBXBv/TOxfanp8ctN5PrbEW56wU03zn5WbkvLoyuLp1eLXlmuXFxeLX+T++pnB9Vjdd3u4rbmggHTTRTAX+n1eg+X9YWFhVdFAfznsh3LE2VfrMfq4GzT45fhKDdT9vsZeO8Hbrhpx9nPzu3CcyXw6qETo+uHT94qf+Wx9PPjut2TW1s9A6aY8oGP8oxfFL3D5VPA431Hh8Ph7vH7A6umx3YeDtz0gptunP0s3aLorZa/KH51EXQqf7bXbcKtvZYBGxLn4cBNL7jpxtnP0o0CKB0KIKwZ5+HATS+46cbZz86Nl4DlQwGENeM8HLjpBTfdOPtZuV1Yft4HPu78EIhLCbS6bndxy+4PII7zcOCmF9x04+zn5Fa+52+y6N1ym/h0cPmZ7PPkur2wW3Z/AHGchwM3veCmG2c/N7fVgjd+lu82twvLNuXP8brd6ZbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/gBeRwWDwuaqq5sp6LA/E9s7IkXpfE5yHAze94KYbZz/cNOPu1l67gKkmSt4bouz9V6/X2xbrO4bD4amyP5azsf9M0+M6DwduesFNN85+uGnG3a29hgHTzKYofb8bZe+rpQDG8mBs76sfjAJ4semBnYcDN73gphtnP9w04+7WTr2AqSbK3u/F4sG6AEbhOx7ZUz8e60udTmdLk2OX4VhZuXkzOaU44aYX3HTj7IebZtzdWisZMJ1E+XtNFL/Xl/Uoel9bWFjYHttPxP5d9c/E9uVut7u5yfFHAAAAIEdbPQOmlCh37xnn96MAfjeK30dj+elY7p34mUtNj19uItffjnDTC266cfbDTTPubu20DJCgPAM4fg/gI7F+ouyL7VgdnG16zDIc5WbKfj8D7/3ADTftOPvhphl3t/baBUw1VVW9szzTF/ns3NzcK2L7aHkfYGwv9vv9qulxnYcDN73gphtnP9w04+7WZseADYjzcOCmF9x04+yHm2bc3bL7A4jjPBy46QU33Tj74aYZd7fs/gDiOA8HbnrBTTfOfrhpxt0tuz+AOM7DgZtecNONsx9umnF3y+4PII7zcOCmF9x04+yHm2bc3bL7A4jjPBy46QU33Tj74aYZd7fs/gDiOA8HbnrBTTdufs+eOz9avrD8fLfYt/rYFJwj121ju2X3BxDHeThw0wtuunHyKwXv+v5joyuLp1cL3y23peXVfeUxlxLodN02mlt2fwBxnIcDN73gphsrvwvPFb2yLMXvxpVrt+2rnx1Uj9V122Bu2f0BxHEeDtz0gptu7PwmSuDVQydG1w+ftCt/ltdtA7ll9wcQx3k4cNMLbrqx9Iuit1r+ovjVRdCp/Nletw3ilt0fQBzn4cBNL7jpxtKPAigdd7fs/gDiOA8HbnrBTTd2frwELB93t+z+AOI4DwduesFNN1Z+fAjEIu5u2f0BxHEeDtz0gptunPz4GhiPuLtl9wcQx3k4cNMLbrpx8+OLoPXj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/AHGchwM3veCmG2c/3DTj7pbdH0Ac5+HATS+46cbZDzfNuLtl9wcQx3k4cNMLbrpx9sNNM+5u2f0BxHEeDtz0gptunP1w04y7W3Z/gBeBqqreORgM3h753HA4/I3xvgOxvTNyJNbnmh7beThw0wtuunH2w00z7m7ttQyYSrZv374Qpe9bZb3f7/96rP97FL4dsTxV9sVyNkrgmabHdx4O3PSCm26c/XDTjLtbWz0Dppht27a9vCyj6H0qyt+fROk7GMt99eOx/2LTYzsPB256wU03zn64acbdrY1+AdPPS/v9/jui6J2O4vdTsTwe2VM/GOtLnU5nS5MDl+FYWbl5MzmlOOGmF9x04+yHm2bc3dqrGDD1DIfD3ZEvRj4fRXDXxP7L3W53c5NjjgAAAECO9toFTD29Xm8Q3Ih8Ogrg3np/FMBLTY9ZbiLX345w0wtuunH2w00z7m7tNAuYWqLcvT8K3z+U9Vi+OfK9KIIPx/JE2TcuhWebHr8MR7mZst/PwHs/cMNNO85+uGnG3a2tngFTysLCwtYoeO8dv/x7qt/vv7bsr6rq6HjfYuyrmh7feThw0wtuunH2w00z7m7tNQ3YkDgPB256wU03zn64acbdLbs/gDjOw4GbXnDTjbMfbppxd8vuDyCO83DgphfcdOPsh5tm3N2y+wOI4zwcuOkFN904++GmGXe37P4A4jgPB256wU03zn64acbdLbs/gDjOw4GbXnDTjbMfbppxd8vuDyCO83DgphfcdOPsh5tm3N2y+wOI4zwcuOkFN904++GmGXe37P4A4jgPB256wU03zn64acbdLbs/gDjOw4GbXnDTjbMfbppxd8vuDyCO83DgphfctPLsufOj5QvLz/eLfauPTcE5cu1wc3XL7g8gjvNw4KYX3HRSCt71/cdGVxZPrxa+W35Ly6v7ymMuJdDt2uGmHwogrBnn4cBNL7gJ5cJzRa8sS/G7ceXabfvqZwfVY3ftcJMPBRDWjPNw4KYX3MQyUQKvHjoxun74pF35s712uEmHAghrxnk4cNMLboKJorda/qL41UXQqfxZXzvcZEMBhDXjPBy46QU3wVAApYObZiiAsGachwM3veAmFl4Clg9umqEAwppxHg7c9IKbUPgQiEVw0wwFENaM83DgphfcdMLXwHgEN81QAGHNOA8HbnrBTSt8EbR+cNMMBRDWjPNw4KYX3HTj7IebZtzdsvsDiOM8HLjpBTfdOPvhphl3t+z+AOI4DwduesFNN85+uGnG3S27P4A4zsOBm15w042zH26acXfL7g8gjvNw4KYX3HTj7IebZtzdsvsDiOM8HLjpBTfdOPvhphl3t+z+AOI4DwduesFNN85+uGnG3S27P4A4zsOBm15w042zH26acXfL7g8gjvNw4KYX3HTj7IebZtzdsvsDiOM8HLjpBTfdOPvhphl3t+z+AOI4DwduesFNN85+uGnG3S27P8CLQFVVH4jsGwwGf7ewsLB9vO9AbO+MHIn1uabHdh4O3PSCm26c/XDTjLtbey0DppJ+v//WyGvH62+LwvflKHw7hsPhqbIvlrOx70zT4zsPB256wU03zn64acbdra2eAVNKlLsPR+H787Iey1dH4ftW5LHyjODEz1xsenzn4cBNL7jpxtkPN824u7XRMWC6eaDX6/1MWRm/DPynkc9F9tQ/EOtLnU5nS5ODl+FYWbl5MzmlOOGmF9x04+yHm2bc3doqGTDlzMzMPBRF7x+3bt36suFw+ESUwV31Y7F9udvtbm5y3BEAAADI0V7DgGnm/ih/j2/btu3lZSMK38EogHvrB2P7UtMDl5vI9bcj3PSCm26c/XDTjLtbG+UCppwoeO9fWFjYWtbLJ397vd7DsTxRtmM9Vgdnmx67DEe5mbLfz8B7P3DDTTvOfrhpxt2trY4BU0r55G8UwB9GyVse58myv6qqo7F/d2QxfqZqenzn4cBNL7jpxtkPN824u7XXNGBD4jwcuOkFN904++GmGXe37P4A4jgPB256wU03zn64acbdLbs/gDjOw4GbXnDTjbMfbppxd8vuDyCO83DgphfcdOPsh5tm3N2y+wOI4zwcuOkFN904++GmGXe37P4A4jgPB256wU03zn64acbdLbs/gDjOw4GbXtzcnj13frR8Yfn5brFv9bEpOEeuHW646YUCCGvGeThw04uTWyl41/cfG11ZPL1a+G65LS2v7iuPOZVAp2uHm0fc3bL7A4jjPBy46cXK7cJzRa8sS/G7ceXabfvqZwcdYnXtcLOIu1t2fwBxnIcDN73YuU2UwKuHToyuHz5pWf4srx1u8nF3y+4PII7zcOCmF0u3KHqr5S+KX10E3X1/cz4AAAwwSURBVMqf7bXDTTrubtn9AcRxHg7c9GLpRgGUD26acXfL7g8gjvNw4KYXOzdeArYIbppxd8vuDyCO83DgphcrNz4EYhPcNOPult0fQBzn4cBNL05ufA2MT3DTjLtbdn8AcZyHAze9uLnxRdAewU0z7m7Z/QHEcR4O3PSCm26c/XDTjLtbdn8AcZyHAze94KYbZz/cNOPult0fQBzn4cBNL7jpxtkPN824u2X3BxDHeThw0wtuunH2w00z7m7Z/QHEcR4O3PSCm26c/XDTjLtbdn8AcZyHAze94KYbZz/cNOPult0fQBzn4cBNL7jpxtkPN824u2X3BxDHeThw0wtuunH2w00z7m7Z/QHEcR4O3PSCm26c/XDTjLtbdn8AcZyHAze94KYbZz/cNOPult0fQBzn4cBNL7jpxtkPN824u2X3BxDHeThw0wtuunH2w00z7m7Z/QHEcR4O3PSCm26c/XDTjLtbdn8AcZyHAze94KYbZz/cNOPult0fQBzn4cBNL7jpxtkPN824u2X3B3iRGA6Hf9jr9d5Ub1dVdWAwGOyMHIn1uabHdR4O3PSCm26c/XDTjLtbO+0CpplNUfA+GAXw36LsvbnsiO0dsX2qrMdyNvafaXpw5+HATS+46cbZDzfNuLu1VTJgyomS92RdAKP0HYwSuG/isYtNj+s8HLjpBTfdOPvhphl3tza6BQgwWQBjeTyyZ+KxpU6ns6XJcctwrKzcvJmcUpxw08iz586Pnllafr5b7Ft9bArOkeu2sf1w04y7W1v9AqacO54BfKKqql31Y7F9udvtbm5y3BFAIj/5+lOj6/uPjX70Z0+Obly5dmt/WS/7ymPlZwAA4Hba6hcw5dzlJeC99WOxfanpcctN5PrbEW4CWVoeXVk8vVr0ynLl4vJq+ZvcVz87qB6r67bB/HDTjLtbG90CBLijAD5SngUs671eL3YPzjY9bhmOcjNlv5+B935sYLcLz5XAq4dOjK4fPnmr/JXH0s+P67bh/XDTjLtbW/0Cppiqqj4QJe87kb+J9beM9x2NErg7stjv96umx3YeDtyEEkVvtfxF8auLoFP5s71uG8QPN824u7VWMmBj4jwcuAmFAigfZz/cNOPult0fQBzn4cBNJLwEbBFnP9w04+6W3R9AHOfhwE0gF5af94GPOz8E4lICra7bBvPDTTPubtn9AcRxHg7cpj/le/4mi94tt4lPB5efyT5PrtvG9sNNM+5u2f0BxHEeDtw0slrwxs/y3eZ2Ydmm/Dlet43kh5tm3N2y+wOI4zwcuOkFN904++GmGXe37P4A4jgPB256wU03zn64acbdLbs/gDjOw4GbXnDTjbMfbppxd8vuDyCO83DgphfcdOPsh5tm3N2y+wOI4zwcuOkFN904++GmGXe37P4A4jgPB256wU03zn64acbdLbs/gDjOw4GbXnDTjbMfbppxd8vuDyCO83DgphfcdOPsh5tm3N2y+wOI4zwcuOkFN904++GmGXe37P4A4jgPh5Mb/7cM/Ti7ufvhphl3t+z+AOI4D4eLG/+/XI84u7n74aYZd7fs/gDiOA+HjduF54peWZbid+PKtdv21c8Oqsfqum0gN3c/3DTj7pbdH0Ac5+GwcpsogVcPnRhdP3zSrvxZXrcN4ubuh5tm3N2y+wOI4zwcdm5R9FbLXxS/ugg6lT/b67YB3Nz9cNOMu1t2fwBxnIfDzo0CKB1nN3c/3DTj7pbdH0Ac5+GwcuMlYPk4u7n74aYZd7fs/gDiOA+HjRsfArGIs5u7H26acXfL7g8gjvNwuLjxNTAecXZz98NNM+5u2f0BxHEeDic3vghaP85u7n64acbdLbs/gDjOw4GbXnDTjbMfbppxd8vuDyCO83DgphfcdOPsh5tm3N2y+wOI4zQcvEyqH9x04+yHm2bc3bL7A4jjMhx8UMIjuOnG2Q83zbi7ZfcHEMdmOPiqFIvgphtnP9w04+6W3R9AHKvh4MuS5YObbpz9cNOMu1t2fwAxrn5k8dEf/MGhV9Tbdu+T43+XJh3cdOPsh5tm3N0yuwQkU1XVgcFgsDNyJNbnXujnS/krpeja/sVv1iXQ7n1yFEDp4KYbZz/cNOPutv4tA6aSKHw7hsPhqbIey9kogWde6M+U0lfK32QJtHqfHC8Bywc33Tj74aYZd7f1bxowlUTpOxglcF+9HQXw4r38udtL4LGnbUoSHwKxCG66cfbDTTPubuvXMGCqicJ3PLJnYnup0+lsuZc/e7MERvmbeJm0FKZyQ6lm8mtgisvKys3BX7l4+8vb2efZRm65reSfC264bQQ/3DTj7rZ+DQOmmuFw+ERVVbsmti93u93N9/Jn7yyAZX3ygyGq3PkBl5qyrzyWcU4AAAAArTF+CXjvxPale/lzd74EXBfByQ+GAAAAAMAUEoXvkfIsYFnv9XqD4OwL/Zm7fQjkbvvW/+wBAAAAoBFVVR2NErg7stjv96sX+vm7fQ1MYbIE8lIpAAAAgBm8Tw4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgTaqqOjAYDHZGjsT6XPb5rAfD4fAPe73em7LPo23ien0gsi+u3d8tLCxszz6fNgmvd4bX2yOfi+v3G9nnsx4UN7eZi2v1+lg80Ol0ttzL/5ZSie3bty/ENXs8vN4R121X9vm0xXwQ1+0zW7dufVn2uawHcc1+rVyzcHx/LF+bfT5tEm6PRt4b+VS4/UL2+YAQ8ZfYjhiKU2U9lrNxE53JPqeW2RSOHwy3fwu3N2efTJvEsL+1/ssslm8Lvy9nn1NblH9o45p9q6yH26+X65d9Tm0T9+Ub4pr9V/xisi37XNoknJ6K67US+UK3253JPp82CaevlmJbvMLzn7LPpy3iXnxL+FwPv+9Hno7178V9+XD2ebXBzMzMQ+HzoXq7FPjM82mTuG5vDJ+TZb3cl7H+99nnBELEsB8szyDV23EDXcw8n/UivJ50K4Dh8+G4dn9e1mP56tj+j+xzapNt27a9vCzLb7bh98fZ59My5ReT3y2Fwq0AhtN7ss9hPSglqZTaiV2b0k6mZcoz7feNfUphCtd3J59Sm2yK6/btmLPXzc7O/lx5QiD7hNoirtvHw+2xie3vZp4PiBE3zPHInontpfKbROY5rQeOBTB4IP5S+5myMn4Z+E+zT6hlXlpetgmv0/cZ/WNbiOv1e7F4MNy+ZlgAF8uz0+Ufpvn5+V/MPp+2CJ+PlWfZ49r9diz/KBx/Ofuc1oNSKmJxf/Z5tMn475FrkS/F5kuzz6ctxm8BuvXLcdyj/1MKfOY5gRBxwzwx+V6W2L7c7XY3Z57TemBaAFcZv8Txj67v34l7cnfki9nn0RYxb68Zv0/uPscCeN+4PIzvy/PZJ9MW4fKJcr3Gmy8pL3WnntA6EE6/Gffn72SfR5vELyE/PX7f5i/F8huRv8w+p7YIp5+vfcoznPH3yv86/vsN68T4JeC9E9uXMs9nvTAugPeXv9zql0sdib/YQnFww+X9ZOUl0nF+P/KfMX8fLS9NZZ9XG5T3oobTZ8ebpSRdTT2hFim/iMS1+tt62/HVknD8ShSmV2afR5uUD36U97qPN1efdXf6+7IUv3D6rfKezXD91+zzASHihnmkPAtY1sf/0J7NPqf1wLUAlr/cFhYWtpb18knu7PNpi+IVPv9Q1st1K29Kj9WXJJ9W67g9AxgF8FfqDw/Effmq8Pvn7HNqi/EHP86NNx+I9W+mnlD7lPfK/TiWD2afSJvEdXpfeP3qxHb5EIjFy8BRbPvh8xdlvcxdbO/PPicQI26ao+OX2RbdvrahUN4nEUPyncjflDdyZ59PW4yfbflheC2P82T2ObVFKbXlqw3G9+Wp8ltu9jm1Tfmam/KMe3nGbG5u7hXZ59MW5f2o5VWFuH6HXZ61rRl/3caHwu+T5Zfn7PNpk/n5+Z8Np//OPo914MHyVWflgy3l3nT5dHOhvNxb7sXIu4pj9vkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAePN/qFSLrlicHTQAAAAASUVORK5CYII=\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Plotting a discrete (X, Y) point series\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" x = range(10)\n",
|
|
" y = [i**2 for i in x]\n",
|
|
" figure.plot(x, y, line=False)\n",
|
|
" \n",
|
|
"# or equivalently plotting a discrete (X, Y) point series, as we would do with matplotlib\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" x = range(10)\n",
|
|
" y = [i**2 for i in x]\n",
|
|
" figure.plot(x, y, \"x\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"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": [
|
|
"# But we can also plot a function, by automatically\n",
|
|
"# evaluating it on the given interval\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.sin, (-2, 2)) # Plot sinus on [-2, 2]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"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": [
|
|
"# We can also do the same forcing replot to use some evaluation points\n",
|
|
"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": 8,
|
|
"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": [
|
|
"# And we can plot multiples graphs on the same figure\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(range(5))\n",
|
|
" for i in range(8):\n",
|
|
" figure.plot(lambda x: np.sin(x + np.pi * i / 4), (-10, 10))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Advanced plotting\n",
|
|
"\n",
|
|
"We can do more elaborated stuff easily with `replot`."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"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": [
|
|
"# Plot with a label on the axis, and a title for the figure\n",
|
|
"# Note how the legend will be automatically added when a \"label\" is found!\n",
|
|
"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": 10,
|
|
"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"
|
|
},
|
|
{
|
|
"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"
|
|
},
|
|
{
|
|
"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"
|
|
},
|
|
{
|
|
"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"
|
|
},
|
|
{
|
|
"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": [
|
|
"# We can also pass these options directly to the constructor\n",
|
|
"# Here, we force the legend to be at the best location\n",
|
|
"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, (-10, 10), label=\"sin\")\n",
|
|
" \n",
|
|
"# But we could also not constraint it (best location will be choosen)\n",
|
|
"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, (-10, 10), label=\"sin\")\n",
|
|
" \n",
|
|
"# Or just say we want a legend (same as not constraining it)\n",
|
|
"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, (-10, 10), label=\"sin\")\n",
|
|
"\n",
|
|
"# Or force it to be in the lower right corner\n",
|
|
"with replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=\"lower right\") as figure:\n",
|
|
" figure.plot(np.sin, (-10, 10), label=\"sin\")\n",
|
|
" \n",
|
|
"# Or explicitly disable the legend, even if labels are found\n",
|
|
"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, (-10, 10), 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"
|
|
},
|
|
{
|
|
"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": [
|
|
"# We can also force the range of the axis\n",
|
|
"with replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=False,\n",
|
|
" xrange=(-20, 10),\n",
|
|
" yrange=(-3.0, 3.0)) as figure:\n",
|
|
" figure.plot(np.sin, (-10, 10), label=\"sin\")\n",
|
|
" \n",
|
|
"# Or equivalently\n",
|
|
"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.xrange = (-20, 10)\n",
|
|
" figure.yrange = (-3.0, 3.0)\n",
|
|
" figure.plot(np.sin, (-10, 10), label=\"sin\")"
|
|
]
|
|
},
|
|
{
|
|
"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": [
|
|
"# Passing extra arguments to matplotlib plot command is as easy as\n",
|
|
"# passing them to replot plot command.\n",
|
|
"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, (-10, 10), linewidth=20)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"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"
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[(0.9677975592919913, 0.44127456009157356, 0.5358103155058701),\n",
|
|
" (0.21044753832183283, 0.6773105080456748, 0.6433941168468681)]\n"
|
|
]
|
|
},
|
|
{
|
|
"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": [
|
|
"import seaborn\n",
|
|
"# You can also tweak the palette used, either with a seaborn palette\n",
|
|
"with replot.Figure(palette=seaborn.color_palette(\"dark\", 10)) as figure:\n",
|
|
" figure.plot(np.sin, (-10, 10))\n",
|
|
"\n",
|
|
"# or by passing it a list of colors as RGB tuples\n",
|
|
"palette = list(seaborn.color_palette(\"husl\", 2))\n",
|
|
"import pprint\n",
|
|
"pprint.pprint(palette)\n",
|
|
"with replot.Figure(palette=palette) as figure:\n",
|
|
" figure.plot(np.sin, (-10, 10))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"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": [
|
|
"# It is not mandatory at all to use a with statement\n",
|
|
"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, (-10, 10), label=\"sin\")\n",
|
|
"fig.show() # But in this case, we must show the figure"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"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": [
|
|
"# NOTE: Passing tuples to the plot function uses\n",
|
|
"# the tuples as (x, y) point series, which is not the standard matplotlib\n",
|
|
"# behavior.\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" x = range(10)\n",
|
|
" y = [i**2 for i in x]\n",
|
|
" figure.plot(zip(x, y))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## One-liner plotting\n",
|
|
"\n",
|
|
"You can also make plot with a one-liner."
|
|
]
|
|
},
|
|
{
|
|
"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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAG4CAYAAADVDFZ+AAAgAElEQVR4nOy9B3hc1bku7IQk555+zzlwuBd8wJZGev7/nNyLDQQCCcGENJKQkEY4gZCQQCqkUGyKsTG2wbji3nuXLcuSJVkukixLVrEsuah3aaQZdcmdhADfXd+eUbGiMqO196y9Z73v87zPFGlm1t7v2t969yrfGjMGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPrwiaioqDaXyzV7NB8Wn/us+HyjePrJof4nOjr6GcEywdpRl9L3W7eL7zgpfu+YeDw1bty4/0/m+0aC+J1YwW7xu9PM/F7xfV8V31somM7HExER8fmRziEAAAAAAIBpiIyMfIQNoN+AfGy4/xX/s1Fww8D3x44d+6/9XwtTUyf45ID3fiJrAMXn08Tvv8bPhYn6ijBO0TLfN+C7uXx1A99nk2a2AeTzIL7zcf/3/4jP38BzCAAAAAAAYBmEAdkr+GXBj9hUjfC/gxrAgbDQANYO/F6zII7rp4OVzwoDyOda8AtmficAAAAAAEBAuOmmm67nYU5+Lh6zBXcO9b/ibzOFQWoW9HJPnOBWYYwixfs5bGgiIiJu8f/fAcGrgqX+/3uB3x/MAIrP/1H8Xy6bLMFD4vV/DfHzn/T/T+/3it+70/8dj4rXJ/zDqVni9Q8GfOY9wanib7vF45khTN73eIiav99f5rSbb7753/x/4+94V3C9f/g5t+dY/fgED5/7zwOXIU68HjvYQURGRv6H//s+5CFg/2/dN/Ac+o/rZ+K9IsEM/m3BPf7zv8x/zL1D6uPHj79x4HeIvy3n/xfvbRdc4v+eD/jvN9xwwz+I5yv8mvNw+pZx48b9z6G0BwAAAAAgjCCMxB8EH/Y/Z8NxVRiEfx7q/wfrARTm41Y2NP3NSyA9gOL3fite1/cYD78J84rX/2Oo3x/4vcJQfU187kLPb4vPjuPX/Xsy+TNsfsb459ex8RniuwftofSbunNjx479W//rFDZU/f4+TzBPPP2U/3teEK9PD3UM/s98xMav5/XAc8h/E/xLjyFmoy1eX+p/7geWdzAd/Hq19RhS8f9viHP2734zub/n/8Tfl4r34ocrMwAAAAAAYQJhApLFw8f5+Y033vj3bJ4EfzXU/5tpAMVnSgYuPPGbt0eHKe813yv+P0lw24Dv4B6vxP6fEa9/P9R3DlW+ft/HBnBhz2tRvrfE64P9PneJF7n0vOaeQ7/Bu2uo3xo4BDzwHIrfWCNeHx/wmcTRGEDukez/PeK7b/D//pd73hOm8A5+j3sShyozAAAAAABhAGEMbuMeuJ4hT7/R8fAQ51CfMdkAXhGvy/v/vmDlcAZ0EAPIJnL+gP9ZyEOnw5VliO8e0gD2nwMonk/n8vqf95ipMwOOo0bwm0P91hAGsP/wbbJ4vXfAZzaNsgfwGr3E3z/j//1cv+Zc7kx/mSeMdJ4AAAAAAHAweF6bMA3/d8B7X/bPT/v/h/iM2T2AL/f/H56bJt77m6HKPNoeQKsMoP9z3AP4WP/P+IfRPzHUb43UAyierx6pB1A8/2827P3KNTEQA+g3rR9y+p7+7/tXIQ+7ChwAAAAAAGfjk9zrM8j71wlz0Cr4zmAfYtPIiyn4uXjc9R//8R83+efdfTTAeJwRBuPXPJ9P/N9R/3vXrLIVf/+NeH32+uuv/0d+zY88d068/59DFXqQOYAPic+cZwPFr2+99dbx/Jrz7A31maHgT4fT6i/bH8VnvuMv97AGkM8Vzwsc458DKMrwv8XrquHSugw0gAPPofiNe8RvvN9j0P2Lbbr7mzleBMPzBPn3/Mf5RiAG0P+/vCBm/Ri/4WPDL96rEE+vG+k8AQAAAADgQAgz8U+8mpUXXLCZ6f83YQQWiffb/WZj5SCfvV28XxrlW1G6SfxvRJRv9Sn3GmZzL5T/e55iQ8HDjGwEo/2JoKP8q2zH9BmP5/jz4r1U8XiMTdgQxf5k1LWrgHf3K9OjUb7VrDyceaL/HEL/UGrPZxYO/tU+cO8jryL2H8+xW2655V/YPIn3uqL96Wf8vYRsKLv8Bsoom3g9w38cR5mc2Hmw3xi4Clhwcb+V1NecQ/H4Y/G6mMsS5Vuxu6Pfb/botdg/bL6Pz3n/7/DPVfT6mdb/czzfU7y3jM8Xn3ue0zic8QYAAAAAAACsx8fYgPZ/w29mZ6kqEAAAAAAAAGAheCUx99KO8Q/J8o4n/rmGQ64sBgAAAPpBBMxf9B+OcblcU8Rd9HcFZw6VrBUAAEAleCGMf9Vvnn+4PS8yMvKHqssFAADgBHzKn2g2v2eytX9i9Vp+Lh5vjvLvgAAAAAAAAACEEfyr4AwDKEzfq8IEPt3vb43qSgYAAAAAAABYgv4GMMq3H+Z/9/ubm1f+qSsdAAAAAAAAYDoG9AAuH5AiwnvTTTf93Ujf8dFHHxEAAAAAAM6Clf4CsDkGGQL+Wc/f+mfRHw5ciTo6LlJ7OxjuZJ2htz6E3noReutF1tkqbwE4AAMM4F3cC8jPIyI4f21UQiDfwQGDK1NbGxjuZJ2htz6E3noReutF1tlKfwHYGLwDgT+T/ibxfJL/Pc6O/5jgnMjISFcg34OAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdehAEEpIGAoQ/RQOhF6K0XobdN6Omii+vj6PJba43nVuqt2j8ADgcChj5EA6EXobdehN42YEMbXVqwmd774zt0ZdoyamvqtFRv1f4BcDgQMPQhGgi9CL31IvRWfP6rPHR51mrD/F2euZraK5ss11u1fwAcDgQMfYgGQi9Cb70IvdWxo6iWrkxd6jN/8zdRW31bSPRW7R8AhwMBQx+igdCL0FsvQm817MwroatTFhrm7+LKGEvn/Q3UW7V/ABwOBAx9iAZCL0JvvQi9Q8+u1Hy6+sI8w/xd2JpEbS3nQ6q3av8AOBwIGPoQDYRehN56EXqHkK0X6Pz+Y4bxY56PzzDeC7Xeqv0D4HAgYOhDNBB6EXrrRegdIracpwtbEg3jx71/XWmnlOmt2j8ADgcChj5EA6EXobdehN4hoKeTLq7Y7TN/UxZSZ16pUr1V+wfA4UDA0IdoIPQi9NaL0Nvi81vfSpfnbfLl+Ht9qbHyV7Xeqv0D4HAgYOhDNBB6EXrrReht4bmtaKIrM1f50rzMWmPk/FNeJhhAQBYIGPoQDYRehN56EXpbw46zNXTltSWG+bu0cIux24fqMvXordo/AA4HAoY+RAOhF6G3XoTe5rMzp5iuTl7gy/G3eg+1eUOT4y9QvVX7B8DhQMDQh2gg9CL01ovQ21x2HT1JV5+f68vxtz05pDn+AtVbtX8AHA4EDH2IBkIvQm+9CL1NIuf425fWm+Ov+8DxkOf4C1Rv1f4BcDgQMPQhGgi9CL31IvQ2gZzjb3NCX46/9AL1ZRpGb9X+AXA4EDD0IRoIvQi99SL0lmRTJ11atstn/l5eRJ35ZerLNILeqv0D4HAgYOhDNBB6EXrrRegtce7qWujy3I2+HH/TllFHcZ3yMgWit2r/ADgcCBj6EA2EXoTeehF6j/K8lTfSlRkrfTn+Zq+h9mqv8jIFqrdq/wDYCFFRUV+OjIz8YXR09DPi8dOBfAYBQx+igdCL0FsvQu/g2XGmiq68ttiX42/RVmpztysvUzB6W+0pAIfg+uuv/0dhAJ/reS2ezwrkcwgY+hANhF6E3noRegfHzhPn+nL8rYmlNm+38jIFq7d1jgJwGj4VHR19LiIi4v/cfPPN/+ZyuX4byIcQMPQhGgi9CL31IvQOnN2Hc/ty/O1MsWWal0D0ttpUAA4CD/9GRUVdFYwXLz8ZyGc4YHR0+CoTGN5knaG3PoTeehF6B8C2C3Qh9qhvpa/g+aRM9WWS0NtiSwE4BePGjfsfPOwrTOC94jFPcHUgnyMAAAAACHN89MEH9P7OZF+C5xfn0weny1QXSRpW+wrAIeCFHy6X6x7/y08IA5h+yy23/MtIn+NKhDtGPYgeAr0IvfUi9B6Gnk66tHSHr+fvlUXUWVCuvkwm6G2xrQCcAmH4nhIm8Ev9XvMikBGHgTlgcGVSPZ8BDM2cEeitD6G3XoTeQ5wXzvH3zgZfjr/py6mjpF55mczS21JTATgKn3C5XFMEfyz4dERExGcC+RAChj5EA6EXobdehN6DnJOyBroyY4Uvx9/b66i9xhk5/gLV22pTAYQ5EDD0IRoIvQi99SL0vpYdhZV05VV/jr/F2xyV4y9QvVX7B8DhQMDQh2gg9CL01ovQu49dWWfp6kvzfTn+1u2jtmZn5fgLVG/V/gFwOBAw9CEaCL0IvfUi9PaxOyW7N8ff+d2HHZnjL1C9VfsHwOFAwNCHaCD0IvTWi9rrLYze+ZjDvTn+ug9mqy+TxXqr9g+Aw6F1wNCM2jcQmhF660Wt9W7upovr43zm76X51JV5Rn2ZQqC3av8AOBzaBgwNqXUDoSGht17UVu/GDrq0eLs/x9+71FlYob5MIdJbtX8AHA4tA4am1LaB0JTQWy/qqHd7TTNdnrPel+PvjRXUUdagvEyh1Fu1fwAcDt0Chs7UsYHQmdBbL+qmd0dpg5HY2cjxJ0xge22z8jKFWm/V/gFwOHQKGLpTtwZCd0JvvaiT3p0FFcZwr5Hjb8kOYxhYdZlU6K3aPwAOhy4BA9SrgQCht27URW9e4HH1RX+Ov/VxYZnjL1C9VfsHwOHQIWCAfQEDeutD6K0XddC7O/mEkeLFyPG350jY5vgLVG/V/gFwOMI9YIDXBgzorQ+ht14Ma72F0buw65Bvpe/zc6n7UI76MtlAb9X+AXA4wjZggIMGDOitD6G3Xgxbvb3ddHFtrD/H3wLqPHFWfZlsQBhAQBphGTDAIQMG9NaH0FsvhqXe7na69O5WX5qXVxdTx+lK9WWyCWEAAWmEXcAAhw0Y0FsfQm+9GG56t9d46fJba33mb8YKai9zKy+TnQgDCEgjnAIGOHLAgN76EHrrxXDSu6Oknq5MW+bL8ffOBmqva1FeJrsRBhCQRrgEDDCwgAG99SH01ovhonfnqXK6+vIiX46/pTupralTeZnsSBhAQBrhEDDAwAMG9NaH0FsvhoPeXRmFdPXFeYb5u7AxXtscf4Hqrdo/AA6H0wMGGFzAgN76EHrrRafr3Z2YaRg/I8dfbKrWOf4C1Vu1fwAcDicHDDD4gAG99SH01ouO1Ztz/O042Jfj73Cu+jI5gDCAgDQcGTDAUQcM6K0PobdedKTe3i66uGavz/xNXkCd2UXqy+QQwgAC0nBcwAClAgb01ofQWy86Tu+Gdrq0cIsvzctri6njTLX6MjmIMICANBwVMEDpgAG99SH01otO0ru92kuXZ6/xmb83V1F7RaPyMjmNMICANJwSMEBzAgb01ofQWy86Re+O4jq68ro/x9/cjdRe36q8TE4kDCAgDScEDNC8gAG99SH01otO0LvzZGlfjr/lu5DjT1Jv1f4BcDjsHjBAcwMG9NaH0Fsv2l3vrvRTdPUFf46/LQeoreW88jI5mTCAgDTsHDBA8wMG9NaH0Fsv2lbv1gvUnZDRl+MvLh05/kzSW7V/ABwOWwYM0LKAAb31IfTWi7bUu+U8XdiW7Evz8sI86jp6Un2ZwoQwgIA0bBcwQEsDBvTWh9BbL9pOb08XXVwV05fjL7dYfZnCiDCAgDRsFTBAywMG9NaH0Fsv2krvhja6tGCzL83L1CXUca5GfZnCjDCAgDRsEzDAkAQM6K0PobdetIve7VUeujxrtS/Ny8zV1F7ZpPzchCNhAAFp2CFggKELGNBbH0JvvWgHvTuKaunK1KU+8zd/E7XVtyk/L+FKGEBAGqoDBhjagAG99SH01ouq9e7MK6GrUxYa5u/iyhhjDqDqcxLOhAEEpIEGQh+qbiBA6A2Gp95dqfl9Of62JiLHX4j0Vu0fAIcDDYQ+hCHQi9BbLyrRu/UCnd9/rC/HX3wGcvyFUG/V/gFwONBA6EMYAr0IvfViyPXmHH9bEvty/KWdUn4OdCIMIHANbr311vFRUVGzIiMjf+hyuR4N5DNoIPQhDIFehN56MaR6ezrp4ordPvM3ZSF15pUqP37dCAMIXIPo6Oi0G2644R9uuumm64URTArkM2gg9CEMgV6E3noxVHq317fS5XmbfDn+Xl9qrPxVfew6EgYQ6IXL5ZokDGBcv7c+Fcjn0EDoQxgCvQi99WIo9G6vaKIrM1f50rzMWmPk/FN93LoSBhDohTB/L0RFRR0QRvBh8firyMjIzwXyOQ4YHR2+ygSGN1ln6K0PobdetFrvznM1xq4ehvlbuIXa3W3Kj1lnss5W+wrAIRCmb7Jguv/lx8Xz04F8jgAAAABgGHxQWkPv+XP8/XljHH30/l9UFwkQsNBSAE5CdHT0Yy6Xa3PPa2EA3TwfcKTPcSVCD4EeRI+QXoTeetEqvbtTT9LV5+f6cvxtT6b21vPKjxVEDyDQD/6FH4f8L68TzwsD+RwHDK5MquczgKGZMwK99SH01oum6805/val9eb46z5wHDn+bETW2UJLATgNwvT9VPA5l8v1cnR09F2BfAYNhD6EIdCL0Fsvmqo35/jbnNCX4+9YgfLjA/9ab6s9BRDmQAOhD2EI9CL01oum6d3USZeW7/KZv5cXUWd+mfJjAwfXW7V/ABwONBD6EIZAL0JvvWiG3u11LXR57kZfjr9py6ijuE75cYFD663aPwAOBxoIfQhDoBeht16U1bu9vJGuzFjpS/Myew21V3uVHxM4vN6q/QPgcKCB0IcwBHoReutFGb07zlTRldcWG+bv0qKt1OZuV3484Mh6q/YPgMOBBkIfwhDoReitF0erd2d2EV2dvMAwfxfXxFKbt1v5sYCB6a3aPwAOBxoIfQhDoBeht14cjd7dh3P7cvztTEGaFwcRBhCQBhoIfQhDoBeht14MSm/O8bf3qG+lL+f4S8pSXn4weL1V+wfA4UADoQ9hCPQi9NaLAevd3E0XN8b7zN+L86kr47TysoOj01u1fwAcDjQQ+hCGQC9Cb70YkN6c42/pDp/5e2URdRaUKy83OHq9VfsHwOFAA6EPYQj0IvTWiyPpbeT4e2eDL8ff9OXUUVqvvMygnN6q/QPgcKCB0IcwBHoReuvF4fRuL3PTlRkrfDn+3l5H7TXNyssLyuut2j8ADgcaCH0IQ6AXobdeHErvjsJKuvKqP8ff4m3I8RcmhAEEpIEGQh/2NBBeTyNVl2dTcWEsnc5ZR/nHF1LesXcoN/1tOpmxgAqzV9G5UzupsvQYuesrqRWpIRxJOxhArjuN7lqjLhUX7DHqVv7xRUZd4zrHda8wZ42oi3upqvQ4eRrdys+bUzmY3l1ZZ+nqS/N9Of7W7TMWgKgup5Vsbe0md105VZSk0rn8HUZ9O5kx36hrRn3LfJdO566nktNxVFORR94mj/Iyy+it2j8ADofqBgK0ng11ZUbQy0j+PSXv/ArtWz8xKB7Y+gAdS3xOBNPVwjieoJaWLuXHBI5MFQawtfU8VVfkUEHWckqLf4YSttw/yvr2W6Pxrqs+jRuQUerdnZLdm+Pv/O7DYZnjr6W5w4hJBSdWUHrCLyl+8+eCrm9JO79Oxw8+LwzjNuNmRfUxBaO3av8AOBwwgOFJbjjzMxdTyp7vBx0QRyI36tlHpxuBF42zfRkqA8h1oKYyz+jVS9we/A3GSEze9bDRM11bdQr1LRC92y7Q+T1H+nL8HcxWXjZz61s3VZakUWbKZIrfdK/p9e3w3sfoVNYSqq8tVn6sI+mt2j8ADgcMYPiQe+Z4aONw7I9MD4pD3j3veIhOZS7B0J0NabUB9HqajeHb5J3fDFl9S9n9HTqXv51amjGPbTC9P/rLB3RxQ5zP/L00n7oyzygvl1nk6Sg8nGvFTcZQTIt/msrOHTRMp+rjH0xv1f4BcDhgAJ1Pr8drDJeFMjAO5P5N91Bu2lvU2FCt/HyAPlplAJsa640eufgt9ymrbwe2fpFOZS0jT1Oj8vNsF7Y3ddCfV+725/h711j8obpMZpCnsJw4MpXiNtyprL4l7/wGnc7dQM02uvGAAQSkAQPoXLa0dNIZEZRGM8/KKsZt+IwI1q87ai5NuNJsA8gT5tnk7994t/J61nfjca8xXNfsbVN+vpVqXdtMl+es9+X4e2MFdZQ1KC+TLNn4ZR16hfYpNH4DmbT9q1RUEGOLHkEYQEAaMIDOI8+DKj2bSMm7Qjf0Fix5bg73SrJJVX2+dKVZBpAbu7Mnt4objUnK69VQ5N5vXknMi1BUn/dQs6O0wTB9bP7+NH8jddQ5O8cfx4xTWUspbuNdyuvVUEyJ+R6VFx1WOicVBhCQBgygs9hQW0pH9z+lPAAGyoO7vkUVxUeUnzcdaYYB5NQsViwksoo8/7W28pTycx8qdhZWGMO9Ro6/JTvoo/f+5Oh4zouJ2FyprkeB8ljSc8pGO2AAAWnAADqD3AtTmLPWVsNvwfD4wRfI09Sk/DzqRBkD2OxtoZzUGcrrzai44U4j12C49z7zAo+rL/pz/G3YT+0t3crzPo6WPITPefr2rb9Dff0JkvGb7zNyDoa6NxAGEJCGUwOGTqyvOUdHYh9XHuhkmbjtS8awierzqQtHawCryjKNSe+q64ssuScpXHsDu5NPGClejBx/e44aOf7skPh7NOQk4aFcSW4VU/f/jNz1FSE7bzCAwKjwxhtjPh6z7ra79q2b8GJt2V5xAaZrOXfGCeQdOeIc2us3FHmRiNfbovzchjuDNQTcY8a5/Patv115HTGNG+6kghPLwye+CaN3Ydch30rf5+dS96GcUeutml6Px4gFyuuIieSV8Zw2JlTXt2ovATgMMWsmTIhdP6FmYMU9tOcHwghmKA8KoI+cbuDE4dcsDFa3G708aQm/oKxDL1NO6puUkzbT+E3ehSEl5ruWrr47uPvbVF9TpPw8hzODMQSNDTV0ZN8TlhoxzuGXfuA3lHX4VV99E8w6/IqxgwPPFbVy+I/rNBsO1ZpI0dtNF9fu8+f4W0CdJ86OWm/V5N1irExbxTfN3KbxHD1OIcOxjesbJ49OjX/ayF9qXWydaOQrbLV4xyQYQCAoxKyZeH/s+olXhzMFvDcssu2rJe9lycHL7KDEAfdM9hyqLEk1kviOVA6eB8bDM5xvzYohaN62qexcsvLzHa4M1BDwkO+BbQ+ari/fRHCKFt53mrfsGrm+tRk3oScz5lkyBM3DjLxDjmpdRkV3O116d5svzcuri6nj9F/n+HOKAeT5cuav8L3dGILl3t6qsqyA6hvPSebeOjaIVtT/1P1PUZO7zrLzCAMIBIyYH4y5LnbdhKJAKm72kWnY71UROSCZmWCXF42wnry6rq3tglQDwSuQedcPs++eecJ+2AzR2YgjGQK+0eM8kmYm2OV9fDlJdF213A4UXDbe+o2HpOM3f97E6+GzRroY1doEpWONly6/vc5n/maspPbywXfdsbsB5CkGvIWkmbGDtwlk0yebgN7Yw7r8BGWmvGTu9SCMJd9gWVIvYACBQLFnzcSHgqm4qfE/NxK/qg4aupBX+XLDaV5D/EUqyFp+zRZtZjUQfHPAyVB5GNes8qYf+LXzh+hsxuH05t42buxMa4h3foPOntxiyU4Jxk43OWtNHTLk4UAnrBLuKKmnK9OXG+bv8jsbqL1u6LmzdjaA3BN2dN+TpunHIyScC9WKG0dO68I3pabdeAhDWZi92vSRNRhAIGDErr/tuWArLs/L4V4f1cEj3MkmjeelmBFsuIcjP/NdY/h2sIBhZgPBprXkzH7TegQ5sbVszxE4st68w4JZuf24h4MXKlk934nJhu20MIKcdsOMsvOcR577qFqnodh5qpyuvrLIl+Nv2U5qaxresNrVANZU5Arz/mVTNDu469v+vXmtn6bEcZl3vuHdjcwo+7HE50y9yYUBBAJG7NqJr4+m0iZs+QIWh1jI2qpC03o2eEL9cA2aVQ0E9/rwXC8zchTy1l6lZ+KV6xIOHExvTsNjxhQDbhTzjs0NaC6p2eSG2chRaMJQHfeUWzVEJ8OujEK6+uI8w/xd2CSuh5aRe7rsaAB9WQzk5/vFGbkdF1KLgr14ObVLRvIfzDGwu79tWqoYGEAgYOxZO2GSzMXHF7LqYBJurCg+amyZJhtUePiNF2sEEjCsbCDc9ZXGUK4ZgZKDPRYjyXGg3jzfz4wUL0f2/ZgaakuUHx/n+DNj1wg2KCWn9yk/nh52J2Yaxs/I8RebaqR+GY3eKsnTRMxKJH5o7w/FjXKB8mPiIWczFovwTUdNRZ50eWAAgYCxevWYT8aum+iVqbicqd0Om2CHA8/lbzehB+N2Y4ii2dsacMCwuhVcJKQAACAASURBVIFg08bHZoax5ZQNTpinZVf26N3W1m3UE3mjdDcV5qyxVQzg+sHztczoDSw4sULtTQfn+NtxsC/H35HgTIJdDCDn+OTUPrJ68IiCMXfORgsSeV68Gem5eKoOG0qZssAAAkEhdt2Ez+1bN/EvMhX3WOKzg84vAwMjT1rmHFGyAYRXWwbS6zcwYISqgeBUNkfjfiJ9nJzaAYtDRkfW+YO/vEcZyb+X1oEn3fOONKqPaSjWVuabkjqGExMrMRyc42/NXp/5m7yAOrODz5FpBwPICyjMSGHF+53bef55yek4Y7qK3HHKpV2DAQSCRuza234Yu37Cn2UbA9ll9zqS56/wnriywXG0k9dD3UBwQ+rb31PueDmBsLu+Srl+TqOnyU3pCfIrL7MOvWLJ6l6zyb0zZkxB4N6rkO5U09BOlxZt9aV5eW0xdZwZXWxVbQDras5S0o6vyZ1/XjGbs9YRaaH4hujg7kek6xuvSB9NrzoMIDAq7Fkz4V5hAttkKi3PhfDlllN/ITqBnqZGOhon3xjnpM0a9bCoqgaCVwrv33SP1HHzPsKcF061jk4hz9GT3V+VF3pwahcnzcVk48ALkmTnOvpucq1fIdxe7aXLs9f4zN+bq6i9onH036XQAPJohOzq7IQtk4Ie1VBNHg0zI51SeuJvgh5ZgwEERo2dKyeMi103oVim0vIcDazYHJmcdoMTlkqd6033GsMOMuVQ2UDwDgyyhoTPAa9iVa2n3ckJbRO23C9tuHkHD9XHMlpyPeEMBlLnYPtXLN05pKO4jq68vsyX42/eRmqvD2wu71BUdX0XF8ZKp0phw23W6thQk2+Q+EZJdrUzL3bhIfRg9FbtIwAHY9sS1z+dOPSs9N0LbxXmpF6CUJL3vEzYOknq/HLuKx5ekS2L6iEiU4boeEV6/nblutqVfEMWJ5mOh+duWrmFVajIhuLQnkelzgVvV1hRkmp62TpPltLVl/05/pbvojaP/GKnkE/xEDGfF87Ith/cg8aJyVXXF1nyiJjsEDjfdAQ60gEDCAyKqKioxS6Xa2wg//vhh3+h3LRZJlzEk5XkaLIzeZWXbG48zj9l1nwk1QaQyUN0xqpNyfrGu6bgpqP/eb1grNCVPa+5abPDahtInrvI+TFlzgmnwSoq2G1ambrSC+jqC/4cf1sOBJTjLxCG8vrm+b3y27rdYST2DqfrmKf6pMU/I3VeeLpM2dmkgPS22ksADoMwfhOFAayMiIi4JZD/7wkY3IUtm0qB57jxBaD6IrQDz+RtJNl5SL49cs0LjnYwgD3kAMe9KzLnh3sOAtn0PdzJE8h5IrmUydl4l+P2yA38/FwwJQci74MtdT2Kz3YnZPTl+ItLDzjHXyAM1fVtpHk58Cupc8lTFCpL0pTXDSvIN1AnjkyVNMe3U2H2qmHrGwwgMBCfEgbw29HR0WnBGkCuUDzUITuRl+e6NdTZd/m+1eQeLt7AXqoxtijxtp0MIJPnV8nugnI07qfipqNJ+bGoIueAPJb4W8nG+Au23A3DbJadSzbyr8mcK+5NHFUPact5urAt2Zfm5YV51HX0pOnHF4rrmxfGyKZ54SktnCZKdX2wkr7h8ZWSJpDr26tDLvqDAQSugTB/3xcPn4iKikoPxgB2dPgqE7Ohtkh6sj7PeaupyO79Tl3Y2tJOxyW3DOINyCuFEbeifKzzQL1Vs8ldLb2bA2+v1FhfofxYQk1PYz0djn1M6twl7/y6uGErVn4soWJtZZ6xE4PMOUtLeEYY7+bAf9fbRZdW7fGZvykLqSvPmvNt9fVdb8oN25Pk9TQqrwehYumZ/fJzcvf/lLxN7kH1tthSAE6BMH//FR0dfRs/D9YADsSf3uumjKSfS1Xa/ZvupsaaQ4N9fViCz9mxA0/JGZldD9H5zkrVhxJyvP/ni5R5UG5IKWn7g9TVVqz6UEKGi921lLJbLvFxevwT9N7VDtWHEnJcvthEh/d+R65R3vcoXb3cMuJvfXT5Kv1pyTbfsO+0ZfRhY3MIjtB8tDRlU8KWz0uds7y0yfTBX/6k+lBCjo4WYZy3PSB17g7FPGxc8wNhrasAHANh/p708yeCZcIQPn/zzTf/20ifMyroIHeMra2ddOLwq1KVllmYvZLa2i4ovxOzku76cmHeviV3ge99lJoaay0tpx17APvqW5eob3KT9fdv+iyVn0tWfixWs7o8UzrFybGkZ6mluVX5saii19Nk9KzInEPuDeNesaF+o6PaQ1dmrfbl+Ju5mjqqmiw9Jquu76JTO6Xnh3NC+La288p1V0V3XaloI+RSgfH0rMrStGv0DoW3AByGYHsAuTINNY+BJ6LKTp7mCbHhtLKwP3kis2zONU6NEort9Vjn4fRWTa5vPNFe5lxyXeUJ/+G0srA/eaGGbL6x0e48EG7kBUSySXx5IdNgKzY7imrpytSlvhx/8zdRW731aU7Mvr75Gso/vlD+eszbpFxrO9CUzQCEET97cmuv3lZ7CcBhcLlcj0dHR3sEF4wdO/ZfR/r/QAKGkc5EcicHXhofTpP1+9Ju3CF1XjiVQqj2HrW7Aewhp9yIk+xx4MnTTti+LFDyDVRO2kzpxjjc0m7I0rc39wLJ89qzYt+XzqUzr8SY68fm7+LKGGrzOO/69nqajRRUMueEF9zwwhvVGtuJnCqNU6bJ1jfeEaqttQsGEJBDoAGDk1PKTgBO2vFQWGwfx0lLM1NelL6IR1rmbzadYgCZvhXpcmliOAmwU3cX6E9OyizbcxBn7NqToPxY7EpOLi47zMk9+a2Hj/Xl+NuaZFqOv0Bo1vXNSed5pa7MuTiw9QGqqchVrqsdaYx0ZC2Tbj84FQ9v5qDaQwAORjABg7ep4e1q5Bqiuxy3v2h/+nYXkEuDwOeg5PS+kJfdSQaQaUaaGJ4r5+Tt43g7Nt6WTeocbJ3k6G3dQkWuJ7zdoMy5TllxH7W9/Aqdj88wNcdfIDTj+ua4JDvaw/OheftL1Xranbxrj+xGAbHrJhTxtq6qfQQwCrhcrr9RXYZgAwbPVeONq2XvXrgbPBTz3sxkZUm69Hy/+C33UVXpcSXld5oBZJqRd4yHPk9lLekdonMCjeTFeZulh8J59aBb47ycwbK28hQd2Pag1Dnfv+FuKjmzP+Rll7m+OdecbDJxJm8jGE5TfaxmTUWedH2LXT+hbc+aCfeq9hJAkOCEzarLMJqAYcbOA8yU3d+h+ppzyi/CkY/3PBXmrCXZ+X68T6TK43WiAWQaOw8k/FK6vvEQHe9HrPp4RqKxfdmhl6WP98i+J+hPV7scp7dquusrjdgke/555Wuo5vcyR3t9NzZUi7ryuPTx8rQY7MwTPPn8y97kChP459i1t/1QtZ8A/IiKivpI8MNhaPxddTlHawi4h+J07nqSXSHMQy4lp+OUX4RDsaG2xNhtQjY48nw0nsul8licagCZvu2VXpfWIXnnN6i2Ml/58QxFnn8l3+Pp20O6paXdsXqrptfjodT9cnk9mdwjFqpdL0ZzfRujGlsnSR8nrxZ2Ug+73cijYccSn5Uzgesmvh+7bsLnVHsKYIxhAHPGjx9/61AcJ8D/o7qcsg2EsUJYcnsl5onDrxlBV/WF2EO+c+dFGrJZ3Jk8WdcOw91ONoCGJsb2Siuk9eDJ/rxqc6gtltQcW7eob6ulU7wweStCboydrrdq+tLEyK/Y5JtcXmRi9bznYPTmLQRz02aT7A08X0vn8nco1yocyDGAe40lTaB39eoxn1TtK7SHy+WKNON/rIYZDYQxj0FyeyUmT3ZnQ6n6QqytKpBe7NJDI+eaTXIghoshKC6MNcUo8RZ0POdL9fHU1xbTkX0/NqG+cc61jWGnt0qakwvPR56CwMPLVpU1UL0rS49R0s6vSx8Pr9KvKE5VrlG4kfeBl5n7G7Nm4v2qfQUwAFFRUd8TTBBMGjdu3P8U5u8tJy4CGYq8Opb3ZDUjUPLwlYr0HZyj6WTGfOl0EEw2KEWndikPJv0ZToagqizTlJsO1jr76BvkaXSH/Bi8Hq9xxx+34TPSx8GrnSuKj4St3qrJizpkVwgzedUnJzu3IkflSHrzgqqsQ3K77fQwaftXjVX6qnUJV1aWZox6wWHs2omvq/YVQD8I0zc5Ojo6Xxi+l/mR3xPPfyuer1NdNjMbCB7CPZb4nCkBhhvF3LS3QtIw811+2bmD0rmvesipS7hXVHUQGchwMwTcoPFCBzM0422WeKFPKCaxc48w3+WbYmDXTzTmDA42zyzc9FZNd3KckebFFAO14yHDVJq5I8tQevMiKp7yYMZUHaaR1F/BDZNubKgtHdUWo3vX3fasal8B9IMwepniwRiX523a+r2fqqxQfpjdQPi2j1ttSi+ar2H+vBG8OAeh2RcYz5MqPXPAlEn3PeSEvaoXewzFcDQEZqWv6CGbd97hhXdCMLus3Otz9uRmU4bfeuhLpzT4NmPhqLcSiph2fl+ab2ePF2bSsa3yK2Z7yKMmRQUxpmyVOVBvNmmnspaadqPB9O14gm0EQ0XOWpAa//OgNNqzZuJDqn0F0A/C6GX1e57W7/kJNSXqg1UNhDFEJ5nfqD95TgSnGagqy5Jebeaur6KCrOWULLk590DyUKKdFhYMZDgbAt4j16weDibfePBiCp4jKDt5v676jLHdGO+OYOb1wPP9hitbOOsdMracpwubEwzzxzt8dKUXGPGHjZCZsYN7BPMzFxu9PqMtK+v80UcfijqbZ6yYl00yfM31sOU+Ki86pF4PDck3B9lHpgWq1bmYH4y5TrWvAPohKipqpeCOyMjIL4rHXMG7/e+tUF02KxsI7gkzI5XCQLKxPHFkqrHPZCBJR3luHxtSNn2+8kiufBvYGG+8yxjSUx0oRmK4GwKek5S885um1zdOHXMyY54xL2eo3raB9a26/IQx1ysl5ruW1H++EdJdb8vZ1EmXlu3ymb+XF1Fn/rW7W5SdTZLernAwHo79kbFVGC/WCCR7AM8lrSg+avSEJ+/8qunlCZctFZ1MI+1azrph267Y9ROvYgGIDTF27Ni/FWZvleBVf/6/q9HR0cv5fdVls7qB4PlOxsIKk4NSf3KCZe4m5+GwnNQZRiBkg3gs6TljeNeMVC5D0Tffzxl7XupgCHzzUH9rYX27w+g5Tkv4pTGhvqe+ZR1+1VjleXD3I6ZNfxiMvFo40OkQOuhtFdvrWujy3I2G+bsybRl1FA8+raO+psi0ucND1Te+ieA6zXWM6xrXucxDU0Qd/IV/OoG5N7T9yXG0xYIFK+DoyLtIDTZlKXb9hJqYNRMmqPYTwPD4WGRk5L/zo+qC9CBUDQQvsuBhBOsCZeiZfXS6cfetOigESl0MAQ/RFZxYbqkRCz1vp7z0OUFNMdBFb7PZXt5IV2asNMzf5dlrqL16+GucF1kEMUTnCPJNsxNGNXQkxzdO4H3u1Hbat27Ci3vXf/rON94Y83HVXgIYBhEREf8nKipqluB6fhRG8NOqy8QIZQPBwwip+3+mPLjJMnnXN43hQNWBIFjqZgh4/h7n+lNdX6Tr285vBjTkq7veZrDjTBVdeW2xYf4uLdpKbe7Ae7/Kiw4buUxV1xdZ8rZwTtiiU3fyda3aPwABwOVy/dw//HtIcLvgYcErgk+pLluoGwiey8CZ4znthupAFzzvMPK2BTIPzI7U0RBwj5kxYd+hvYE85Me7NkBv69l54hxdnbzAt9p3TSy1eYNf7cpzko8ffEF5vRkNedHI6Zy1WOXrEMIAOgTC6BXx1m/934uOjo4Q7xcrKlIvVDUQPI+J5+ipDnqBMmXP96mm8qTyi142YOhqCLg3kCfXq65HgZLn+fDCJegdGnYfzqWrz881zN+FnSlG6heZ7+Ok3KPJ4aaKvDhOZgUyGHrCADoE3OM32PvhmAcwGHJvIAdKNleqA+BQ5BW+vHrYjDxdqqm7IeC5M7yNHC/cUV2vhmLC1kl0Ln+bKb0wuusdEDnH396jvpW+gt2Jcqa7P7n3mXOixpuwg4hV5AVNvJrZ6n2KQfMJA+gQuFyunwk+HRER8c/8mreCE6bwV4LPqS6bHRoIbuw4GSpvL6Q6IPZyw52UdfgVaqgrU3puzA4YdtBbNXkI/1TWElO29jKLPPyWm/6WkfgVeoeIzd10cWO8z/y9OI+6MqzZ2oxHO3iRiBn7V5vFhC2TjDyS4XBjqythAG0Mf7qXD/38aMDrnvc+VF1OOzUQvFPC6dwNRt41VYGRE+xy6oPBttZyOmEIrqWnqdHo3TVzp4RgySvjeY5iU2MD9A4lOcff0h0+8/fKIuo8Zf31zlsX8vaWZiYsD5Z8k829kk7KXgAOThhAG0OYu5zx48ffOhR5TiD/j+py2rGB4B7B8qIUY8/JUAZG3q3BXV+p/PitDBh21Fs1Oc8ZL0xK2f2dkNU3XknOew97A0j0C71NPi+c4++dDb4cf9OXU0dJfUh/39iiLXOJsftHqOrbkdjHqeT0fvT4hRFhAG0Ml8sVOdL/REZG3hGKsgwHuzcQ9bXFxn6Wh2P/2/zel033GglVOaeS7PZyTiAMwfDkeVC1VQXGjYDZ2wQyee4h5/LjxUShmHMFvQc5J2UNdGXGCl+Ov7fXUXuNup4wrgO8YwxvIZmw5X7T6xsvJGKjyTvkqD7voPmEAXQYbrrppusjIiJu6WFUVFS26jI5qYHguTTn8rfT8YPPj2qYmLdtSj/wKyo4sVIE3mxb79trVcBwkt4qyY0zN5yF2avoWOKzoxom5nlWvFsDJ6WursgJ+U0G9L6WHYWVdOVVf46/xduCyvFnNblnjmNSYc4aIzvCaOob32Dkpr5IZ3LXh+UUFvBawgA6BC6X67PR0dH1A+YDYg6gJHnCfE1lHpWcjjPmDvJm6pynj8nbz3HjzdnsK0vSjCTUOvTyjRQwnKy3avLQHW/FxCuJuaHmuXtGfUufYzzn+lZcuNdIEs77YKteWQm9+9iVdZauvjTfl+Nv3T5jAYjqMg1Hrjvu+ipjP+CiU7uMeXv5xxcadS3v2Fyjvp0WRo/rIt9ccP5B6K0XYQAdAmH00v1z/tL9b30yMjLyEfF6ptKCjXG2AQSDDxjQWx9Cbx+7U7J7c/yd331YOsefXQm99SIMoEMgjN4R/2PGgPeT1JSoDwgY+hANhF7UXm/O8RdzuC/H38Fs9WWC3qCJeqv2D0AA4ITPLpfrb8RjsuBj4vk/RUZGfk08r1VdNgQMfYgGQi9qrTfn+Fsf5zN/L82nrswz6ssEvUGT9VbtH4AAwImghdl7RjzeExUV1e2fC/gn3iNYddkQMPQhGgi9qK3ejR10afF2f46/d6mzsEJ9maA3aIHeqv0DECSuv/76f4yIiLhTmL8bVJeFgYChD9FA6EUd9W6vaabLc9b7cvy9sYI6ysxPsG1X6qi3zoQBdDiioqJWqi4DAoY+RAOhF3XTu6O0wUjsbOT4EyawvbZZeZmgN2il3qr9AzAEoqOj0wJgl+pyImDoQzQQelEnvTsLKozhXiPH35IdxjCw6jJBb9BqvVX7B2AICHNXJviToRgVFfVT/h/V5UTA0IdoIPSiLnrzAo+rL/pz/K2Ps32OP+gNmqW3av8ADAFh8L5nxv9YDQQMfYgGQi/qoHd38gkjxYuR42/PkbDN8Qe9wcH0Vu0fAIcDAUMfooHQi2GttzB6F3Yd8q30fX4udR/KUV8m6A2GWG/V/gFwOBAw9CEaCL0Ytnp7u+ni2lh/jr8F1HnirPoy2YBhqzc4pN6q/QPgcCBg6EM0EHoxLPV2t9Old7f60ry8upg6TleqL5NNGJZ6g8Pqrdo/AAEgIiLiwVD8jsvl+rXg01FRUdvHjx9/ayCfQcDQh2gg9GK46d1e46XLb631mb8ZK6i9zK28THZiuOkNjqy31Z4CMAHR0dEewSdvuummv7PqNyIjIx8S/LT/+SPCBB4I5HMIGPoQDYReDCe9O0rq6cq0Zb4cf+9soPa6FuVlshvDSW8wML2t8hOAiRBmLJv3ABaPseJxncvlmmTBb/xOfO9Sfi4e/1O8PhPI5xAw9CEaCL0YLnp3niqnqy8v8uX4W7qT2po6lZfJjgwXvcHA9TbbRwDW4OM9T4QBvFnwFb8pnCEYYdJvXBcREfHP/MQ/DDw3kA9xwOjo8FUmMLzJOkNvfRgOendnFNLVF+f5cvxtiqf2lm7lZbIrw0FvMDi9TfIOgJUQhuwr/HjjjTf+PSeAFswQfE9wr+BqwXhh3j5vxm/xXsPi+/bxbwXy/wQAAGBD/OXYScP4Md8/mEkfffSR6iIBgK1ghmcALAbv+CFM4GbxeFkwX/DZsWPH/mvP32+44YZ/EKYtz4Sf+pj4nlm33HLLvwT6Aa5EuGPUg+gh0IuO1bvtAl3YebAvx9+RXPVlcgAdqzc4ar1N8AyA1RCm7ILgPGEC/2uwv4v3HxZ/d8v+jjCWz4wfP/5G/29+N5DPcMDgyqR6PgMYmjkj0FsfOlJvbxddXLPXZ/4mL6DO7CL1ZXIIHak3KKW3rGcAQgBh8H473N+5x27cuHH/S+Y3eOWvMIAXhfFr83NjIJ9DwNCHaCD0ouP0bminSwu3+NK8vLaYOs5Uqy+Tg+g4vUFpvWU8AwDAAGpENBB60Ul6t1d76fLsNT7z9+Yqaq9oVF4mp9FJeoPm6K3aPwAOBwKGPkQDoRedondHcR1ded2f42/uRmqvb1VeJifSKXqD5umt2j8ADgcChj5EA6EXnaB358nSvhx/y3chx1+Y6w2aq7dq/wA4HAgY+hANhF60u95d6afo6gu+HH8XthygtpbzysvkZNpdb9B8vVX7ByAwfDw6OvqFqKioIvF49uabb/438XxH/1QwqoCAoQ/RQOhF2+rdeoG6EzJ6c/ydj0s33lNeLofTtnqDlumt2j8AAcDlcs3nZM/+7eBy+D3x+A3BParLhoChD9FA6EVb6t1yni5sS/aleXlhHnUdPam+TGFCW+oNWqq3av8ABADe+aPnuTCBaf2eH1VToj4gYOhDNBB60XZ6e7ro4qqYvhx/ucXqyxRGtJ3eoOV6q/YPQADgfX/H+PcD7mcAr+vpDVQJBAx9iAZCL9pK74Y2urRgsy/Ny9Ql1HGuRn2Zwoy20hsMid6q/QMQAFwu12xh9o6Lx5+JxzORkZE/FI8HBN9UXTYEDH2IBkIv2kXv9ioPXZ612pfmZeZqaq9sUn5uwpF20RsMnd6q/QMQGK4T5u/l6OjoCmH6rvofJ/P7qguGgKEP0UDoRTvo3VFUS1emLvWZv/mbqK2+Tfl5CVfaQW8wtHqr9g+Aw4GAoQ/RQOhF1Xp35pXQ1SkLDfN3cWWMMQdQ9TkJZ6rWGwy93qr9AyCB/gtCVAEBQx+igdCLKvXuSs3vy/G3NRE5/sJcb1CN3qr9AxAAhNH7elRUVIngnwQ/9PMjflRdNgQMfYgGQi8q0bv1Ap3ff6wvx198BnL8hbPeoFK9VfsHIAAIo1cp+L3IyEjX+PHjb2WOE8AqYDDUAQN668OQ6805/rYk9uX4Szul/BzoRFzfehEG0CEQRi9xsPddLtfYUJdlIBAw9CEaCL0YUr09nXRxxW6f+ZuykDrzSpUfv27E9a0XYQAdAmH0vipM4K8iIyM/HRERcUsP/fkBlQIBQx+igdCLodK7vb6VLs/b5Mvx9/pSY+Wv6mPXkbi+9SIMoEPA5k/win/eX39iDiAY0oABvfVhKPRur2iiKzNX+dK8zFpj5PxTfdy6Ete3XoQBdAiE0atyuVy3jxmQ9y86OjpZUZF6gYChEVu76D1vCTVlbKKG/W9Q3ZanqXbVI1Tz7gNUveBeqp5/j3g+iWqWf4PqNv2EGvZOocajq8h7Oo1aPS3qyw8GRasNQcfZGmNXDzZ/lxZuMXb76P/3Vm87ec9mUGPaWmqIfZXqNj9FNSu+adQxrmtc5/h57cpvi7/9jBriplFj+nryFudQa3OH8vPnNMIA6kUYQIdAGL24wd6PiIiICnVZBgIBQx9yA1z9zu1Dc+6dw/ztM1S38UlqTF1DLTXlyo8FHJlWGoLOnGJjP18jx9+qPdTm9eX4a6mrpsZjG0Vd+zlVz7t7hLp2x9B/n/9Zqt/+G2o6vpVa3G7l59IJhAHUizCADkFUVNSLgisFvyn4hX4sVF02BAx96I5/kxq3/JjcB2ZR04nd5C06QS211UZPTc//cM9LS0MDNZeeIk9ePLkPLqS6rb/w9dj0a6DrNv2UmrL3XPNZ0F60yhB0HT1JV5+f68vxtz1Z1IFOo64Y9aS/qZt/t6gnT5E7aR55cvZRc8lJaqmvE3Wsk1pbL/jI9a2uRvwtT9TJGHInzqG6DU8I83jXNTcf9TueJU/BYfEZ5BMMtd6gPQkD6BAIo/dedHR03UDytnCqy4aAoQ9lGghuqL1n0qkhfoZvyNjfONcseZAaDy+j1kbM/bIbTTcEnONvX1pvjr+u+KPUmLaOapZ9rc+sLbyPGva9JsxaitTNAU858JxMpPo9k6+5+ahd8TA1Ze0wTKTq82s3wgDqRRhAh0CYvf2DvS8M4M5Ql2UgEDD0oVkNBDe+npMJ1w4pL/oCNR5ZgR5BG9FUQ8A5/jYn+Fb6vvAOeXfNpZrFD/YZs/U/oqbsvUJ/8/f6ZTPYlLmdald/r+/GQ5hO7sVubelWfp7tQhhAvQgDCEgDAUMfWtFANJeepPqdv+trmJc/ZPTctGL3B+U0Te+mTrq0fJev12/qS1S77OG+qQBbnyHvuayQ6M2/4Sk8YsxF7TWewhTyQhPV59oOhAHUizCAzsF1UVFRr0dHR9cLvu8f/n1tzIBVwSqAgKEPrWwgmkvzjXmB/Y1Bc2WR8mPWmWbo3V7XQpfnbqRLL06jxtmP9BmvNT9QZrwMI1hw6JoewfqYF4y5q6rPudP1Bp1DGECHQBi+OcLwHXG5XI+Lxy+LxyfE42F+X3XZEDD0odUNhNEwpg+gJwAAIABJREFU5+yjmqVf8TXM8+6ixqMrMUznUL3byxvp8owV1PHqM1Qzx7eil+d/8nCsHTRtbemipowtxvSDnrLxYhTV5XKq3qCzCAPoEAijlzXmr3v7rhPvn1BRnv5AwNCHoWogeM6WO2lub1qZug0/puYqbA3mJL07zlTRxalvUeObX+/tZWuIm27LxT7c81e/6w99vYG7/6hlbyAMoF6EAXQI/AYw4PdDCQQMfRjqBoIT+tau/JavYV5wr5HTDXMD7a93Z3YRdU59jmre9vf6Lf0KeU8fVX48w9Hofc7d70syzWVe/KCRwFx1uZygN+hMwgA6BFFRUSsEt7tcrkm8H7DgA8L8bRVcrrpsCBj6UEUD0epppYb4N/vN1XoRu4rYWO+ulEzyTn+0r9dv7yu27PUbikZvYO+ipDvInbLIGCpWXS676g06lzCADsHYsWP/VhjAVZz3z78H8FU2f/y+6rIhYOhDlQ2Et/BIb+9M7apvU3PFWeXnI9wZlN6tF6hz525qmOVP7TLvs+TJjVN+DKMh9wY2HdvUm0ya0xW11NcqL5et9AYdTxhA5+FjkZGR/86PqgvSAwQMfai6geBdR4xdHvxDwp6cWOXnJJwZsN7N3dS+an7vkG/dkofDYgU3pyjifa19Ccu/ZExJUF0mW+gNhgVhAB2C8ePH38hbv4mnH3e5XH8jOC06OnrG9ddf/4+qy4aAoQ/t0EBwEmn3gbd6hxh5mzA7rCgNRwaid2tjB7Us/ANVz/HrseWPliRzVkUevu4dEp53NzVl7VJeJpV6g+FDGECHQJi/HYKLxNNPCuP3tnieI7hRPN+tumwIGPrQTg0EDy9Wz/+sb17g9t9Qa1Oz8jKFG0fUu6qBmt55zGeO5txBnqSVYblIh/cPdh9a3HfTkTA7LOcF2un6BkOjt2r/AAQAYfTS/E8/Loxf47hx4/6X/32kgQFDGjDspLcxROfPGVi7+rvUUlOuvEzhxOH0bj19lhre/qpveHTOPdSck6K8vFbTc/KAMfWgJ1G5kxa3yOoNhh9hAB0CYfqO86PL5fqKeJ7U874wgEfVlcoHBAx9aMcGoqW+jmrXP+5P3fFF8pbkKi9TuHAovVuPp1Hd2/f5jNDcL1NLiT4LcprLTxvbFfbddFQoL5PVeoPhSRhAh0CYviXC7B0Uj+6IiIgHefWvMIN/FK8TVJcNAUMf2rWBaPW2G+lhjCG6+feQJz9JeZmczKaWLjpaVUyLCw/SjuoTlFRxmrz+eZatSbt7F3s0LPwetTY0Ki9vqNnSUE91G/w3HUsepOaSPOVlMoN2vb5B6/RW7R+AwMCrf78mDN/d/EKYv38ShvAnwgxGqy4YAoY+tHMDYczTSp7Xm7+N03ioLpMTebymnB5KnkN37H/1Gj5yaAGl7J5L1XN8u7M0Ln/GWJCjuryqaNx07P5jWN102Pn6Bq3RW7V/AGwEYSynCJP5XcGZ4vnYQD6DgKEPndBA8G4hPVvIuRPnGMZQdZmcwsNV5+ju+Kl/Zf56eGfcK7R4zXfIs+n1sFzsESzD7abDCdc3aK7eVnsKwCEQhu+e6OjotfxcPN4sTGBsIJ9DwNCHTmkgPAUpvZP1eY9X7q1RXSa7k4d4uZdvKPPXn7Pz4qgFBrCX19x0JL3j2JsOp1zfoHl6W+sqAMdAmL5XhQl8uuc1rzYO5HMIGPrQSQ2EsUJ4iW9XirqNT1KL2628THZmYsXpgMxfD/+YudWYK6i63Hah51SKMRTs267wBWpt7lBepmDppOsbNEdv6xwF4CjwQhPB/+732n3DDTf8w0if44DR0eGrTGB4k3V2kt6ttRVUu+oR34rNld+ilpoy5WWyK9eeTQ3KADJ/mraS6prblJfdLmwuzTNWovdsH9fa1KS8TMHQadc3KK+3ta4CcAx4b2GXy/Vov9fem2666e9G+hwBgI3xwdXz1LT9aZ8JXPogvectUl0kW2JteVrQBpD5g9R3qflqt+ri2wbvd7mpYY3vpqNh7Xfp/fMe1UUCgCFhrasAHAP/EPDP+r32BPI5rkS4Y9SDTu0haGvpoIaYF3pXbHoLUpSXyW5Mqy4elQFkfjX5bTpZX638GOzC1kY31W38cV+amLKTyssUCJ16fYOj19s6RwE4CsLw3cW9gPw8IiIiKtAcgxwwuDKpns8AhmbOiFP1NlZsJr3jM4Fz76Sm49uUl8lO9LR009cSpo/aBN53YAYdqSpSfhx2oZEmZtcffPVtwb3GwiTVZRqJTr6+wdHpba2rABwFl8v1ljCBjwnOiYyMdAXyGQQMfRgODQSn6uCUHcaKzeR5jl2xaSY5pUvjoSV0cPEDdFfcy6M2gZxCJqYUO7H0ndfzRiqivpuOrcrLNBzD4foGg9Pbak8BhDkQMPRhuDQQnLS3d8Xm7j9qnSaGkzk3xL7qMynz7qaY9HXCyL0+ahPIXHH6CPIE9mPjsY2OuOkIl+sbDFxv1f4BcDgQMPRhODUQvH1XzWJ/mpgNjxvbe6kuU6jZ2uSluq3P+Mzfoi+Q99xx4/3UqmK6/8AMKRP4Zl4sNdvU6Kig76bjs/40MS/a8qYjnK5vMDC9VfsHwOFAwNCH4dZAtNRUUO3q7/om6y//OjWXn1FeppAde3XZtcdeee38vfz6GvraIFvCBcPfHd+MXIH96C3OoZp3H/CtSF8vbjrq65SXqT/D7foGR9ZbtX8AHA4EDH0Yjg1Ea6OnrxeMJ+ufTFReJqvpPZNO1Yvu9xuRHw1pRMqaPPRY2hIpE/hk6gqq8bQqP2a7sKWmvM94L/2KkbBcdZl6GI7XNzi83qr9A+BwIGDow3BtIFpbusidMNu/p+vt5D602LbztKSOs/WCbxGMf9uyhr1Thh2KZJ0vvf8e/Tx9tZQJ5C3mityNyo/fLmxtaqb6Hb/1pyX6LHly45SXqUfvcLy+waH1Vu0fAIcDAUMfhnsD0ZS1i6rn3eWbp7Xzd8YcOdVlMout3ra+xR7CADamrhlxoUaP3t7Wbnoha5uUCfxy0luUU1el/DzYha0t3eROmtd303FgtrEgR2WZwv36Bv9ab9X+AXA4EDD0oQ4NhLcou3cP4ZoV37TVEN1oyfP7ald/z7/Y4z7yFB4JWu8WYRbn5CdImcDPH3iDDlWeU34+7ERPTqwx9cC3GOkJaqmtVlYWHa5v8Fq9VfsHwOFAwNCHujQQLfW1xl6uvtQodxnDpk5Na+LJ2ddrMGrX/7ex8EVG73Vn0+lOCRN4V/xU2lWSrfy82InNFWepdtW3fTcd704ib4AG3Wzqcn2DfXqr9g+Aw4GAoQ91aiCMeYEpi3rzt/GQcEtDg/JyBVz+Rg817H2ld4ixIWEmtTZ3mKJ3XFk+3ZMwTao3cFnhIceaakv08rQY6WF69Yp/U7wX2sUzOl3fIAwgYAIQMPShjg2E93Rab75A7p3x5O63vXHhHiReYdo75CvKbLbe6dWldH/im1ImcHruXuQK7Edjkc7xrX09tiseNlLHhOr3dby+dSYMICANBAx9qGsDwT1/vfu6cm+geG7HxNFGr1/ctN5y1m37JbXUjX5O2Uh6F9TX0UMH5XIFPnt8IzUqXvxgNzZXlVLdhh/3LthxJ801egit/l1dr29dCQMISAMBQx/q3kB48uJ7E/nyzhlNGZuNoWLV5eIVpdxzxD2UvnyGn6OmzB3SPZWB6F3e5KUfHHlXygQ+kbqcqpEr8K80bTy6sndVOvfo8nxOK3ufdb++dSMMICANBAx9iAbC3xvYb64WJ/X1FKQoGxb2ns2g2jU/6Oud5LmKQSz0MEPvOm87PZ2+RsoEfitlPp1zu5XrazfyCu66rb/o69Xd9FNqLs235LdwfetFGEBAGggY+hANRB8N49WTWoUb5o1PCiN4OCRGkH/Dey6T6rY8fY0R9Z5JU6a3t6WbJp/YIWUCv5Q0m07UVirX1m5kvXkv4ZrlD/Uz+s+ZnqII17dehAEEpIGAoQ/RQFxLY+j1xG6qWfa1fkbse9R0fJslc7Y4mXNT9l4jnUvP73HOQiNNjQVD0cHqzUZl3qlEKRP4uYTplFyhz57MwenfTo1HVhjTD3pvPDY/RZ68hKBXeJuhN+hswgAC0kDA0IdoIAYn7+DQlLXTWLXZ0zBXz7+H6ve8RJ6TB4ytv0b93aLR95xKoYZ9r1H1ws/3Gb9lD1Fj+nrDFNpN743nMugz+18btQnkz24vzlKuq13JO9Q0Hl7Wm7Dct0L9AWrY/4bRCzxaM4jrWy/CAALSQMDQh2gghifvH8y7bNTveJaq536mzwzOu8vY5cGdOIeaTsSQtyTXWJ3LDTX3mhkUz1vq66i5JM/YHYK3CeP5XtXz7u77nnfuoLqtv/T1+IRg8YmM3gnlBXSvZK7AxQUHbZ9yR2l9EzcHTdl7RD15ql8d8d181G19htwHFxgLl3jOIK9a7zGGRn0Tn22prSJv0QljC0TOE1m3/nFqO/w2rm9NCAMISAOGQB/CAAbOFrfbWJlbv/03okH+7LUN9EDOvXPovwkDyHP9eJhXJqWLCr0zasrogcSZUiZwak4McgUGUt9qyo39nes2/eTam49g6ppg045ncH1rQhhAQBowBPoQBnB05CFiTujbmL6BGuKmU93mnxlbfxlpWzjp7/x7jCE83nuY53Q1xL5KjWnrjIUm3FPjZL0LG+rpGwffkTKBv85YT24T5rjpQp5/ygnMG1NXU8Pel42e5Jrl3/DVN1HXOE0Q17faVd8xbi4a4mcYKY1ayvLpow/ex/WtCWEAAWnAEOhDGEC9aJbeFU3N9NiRJVIm8EdHl1JlCJIh60xc33oRBhCQBgKGPkQDoRfN1LuhuYN+eWydlAl8OGUenXE7Zz9mpxHXt16EAQSkgYChD9FA6EWz9eZcga9k75IygV9MnEWZJiW6Bq3VG7Q3YQABaSBg6EM0EHrRCr15BerCU0lSJvDehOmUWF6o/PyEG3F960UYQEAaCBj6EA2EXrRS7y1FmdK5AreK71B9jsKJuL71IgwgIA0EDH2IBkIvWq039+Jxb55MbyD3JiJXoDP0Bu1FGEBAGggY+hANhF4Mhd48n4/n9cmYQJ5XyPMLVZ8vpxPXt16EAQSkgYChD9FA6MVQ6c0re3mFr4wJ5BXGDcgV6Ai9QXsQBhCQBgKGPkQDoRdDqTfn+ONcfzImkHMNVkjsu6w7cX3rRRhAQBoIGPoQDYReDLXevNsH7/ohYwK/cXCusfuI6nPnROL61oswgIA0EDD0IRoIvahCb973l/f/lTGBvP8w70Os+vw5jbi+9SIMICANBAx9iAZCL6rSm1f1Li44KJkrcBollBcoP4dOIq5vvQgDCEgDAUMfooHQi6r13l6cJZ0rcNO5DOXn0SlUrTcYer1V+wfA4UDA0IdoIPSiHfQ+WHGGPieZK3DeqUTkCnSI3mBo9VbtHwCHAwFDH6KB0It20ftEbSV9KWm2lAmccmIHcgU6RG8wdHqr9g+Aw4GAoQ/RQOhFO+l9zu2mb6XMlzKBzxxbS/XN7cqPxa60k95gaPRW7R8AhwMBQx+igdCLdtO7ytNCT6QulzKBjx5ZTOVNXuXHYkfaTW/Qer1V+wfARnC5XL8WfDoqKmr7+PHjbw3kMwgY+hANhF60o96NzZ307PGNUibwoYNzqKC+Tvmx2I121Bu0Vm+rPQXgEERGRj4k+Gn/80eECTwQyOcQMPQhGgi9aFe9OVfg9Ny9UiZwUuKblF5dqvxY7ES76g1ap7e1rgJwDITh+53L5VrKz8Xjf4rXZwL5HAKGPkQDoRftrDev6l1WeEjKBN6TMI3iyvKVH4tdaGe9QWv0ttZVAE7CdREREf/MT/zDwHMD+RAHjI4OX2UCw5usM/TWh07Qe2dJNt0VP3XUJvBOwfXn0pUfhx3oBL1Bc/W21lIAjsP111//j8L87bvxxhv/PpD/JwAAAIXIba2iLyTOkOoNXFKcQh9+9KHqQwGAkMJqPwHYCNHR0fcJc5cjmN2P/DrW/y8fE89n3XLLLf8S6HdyJcIdox5ED4FedJLeuXVV9OWkt6RM4IsntpO3tVv5sUBvMFR6W2Q1ACdCGMRnxo8ffyM/F0bwu4F8hgMGVybV8xnA0MwZgd760Gl6F7kb6ZFDC6RM4M/TV1Odt035sUBvMBR6W+soAMeAV/4KA3hRGL82PzcG8jkEDH2IBkIvOlHvGk8rPZm6QsoEfv/wIipr8ig/FugNWq231b4CCHMgYOhDNBB60al6N7V00e8zN0uZwK8lz6H8+lrlxwK9QSv1Vu0fAIcDAUMfooHQi07Wm3MFvpkXK2UC7z8wg1KripUfC/QGrdJbtX8AHA4EDH2IBkIvOl1vzhW48vQRKRN4d/zrFFt6UvmxQG/QCr1V+wfA4UDA0IdoIPRiuOgdU5IrjJxcrsDVZ1KVHwf0Bs3WW7V/ABwOBAx9iAZCL4aT3keqiui+A3K5Amef3E8trReUHwv0Bs3SW7V/ABwOBAx9iAZCL4ab3nl11fSV5LelTODzWVuNRSaqjwV6g2bordo/AA4HAoY+RAOhF8NR75LGJvruoYVSJvCptFVUG4a5AsNRb3B4vVX7B8DhQMDQh2gg9GK46s3m7adpK6VM4PcOLzLMpOpjgd6gjN6q/QPgcCBg6EM0EHoxnPXmYdw/Zm6VMoE8nMzDyqqPBXqDo9VbtX8AHA4EDH2IBkIvhrvevKCDF3bImEBeWMILTFQfC/QGR6O3av8AOBwIGPoQDYRe1EVvTvFyp2SuwJjSXOXHAb3BYPVW7R8AhwMBQx+igdCLOunNyZ7ZyMn0BnLS6VYHp4nRSW8QBhAwAQgY+rCngXB7G+lMVTZlFMXSwcJ1tC9vIe3JeYdict4WzxdQ4qlVlHp2J52qOEbV7kpHN4o60w6GgOtObWOtUZeOFe0x6lZc3iKjrnGd47qXVLBG/G0vFVQep/om96h/i7d9u18yV+CbefuMbehUa+dUvVWzpbWbKhvK6WR5Kh09u8Oob7G58426xow7+a6IeevpeHEcna3OI7fHo7zMMnqr9g+Aw6F7wNCBlQ1lRtBbl/57mn3gKzRlz8Sg+Mb+B2hN2nOioV5Np6tOUHOY5lELN6owBK3CPJ2pzqGE/OW04ugzND3u/lHVt9VpvzUa75La00HdgOTX19DXkudImcDfHd/syFyBOhpAb0uHEZMOnFpBK4/+kl7f97mg69tbB75O6489T0fPbDNuVlQfUzB6q/YPgMOhW8DQhdxw7j+5mOYnfz/ogDgSuVHfkTXdCLzoHbQvQ2UIuA6cq84zevVmxgd/gzES5yQ+bPRMF9WcCqi+lTZ66PuHF0mZwJ+kraAaT6tyDe2ot2pyL19+RRptyphMU/fda3p9W5jyGMWfXELl9cXKj3UkvVX7B8Dh0CFg6ELumeOhjUUpPzI9KA7F2QceEkZzidTQHWgNrTYEjd5mY/j27QPfDFl9m5v0HTp6djt5W9qHLVudt41+nr5aygQ+ckiYTnejch3tordq8nQUHs6dmWD+TcZQXH7kacopPWiYTtXHP5jeqv0D4HCEc8DQhY1erzFcFsrAOJCvxd5Du7PfoprG8Mmr5nRaZQjqmuqNHrlpcfcpq28z9n+REvKXUYNnaIPmaemmF7O2S5nALye9Rbl1Vcq1VKm3avIUlq2ZU+mVvXcqq29vHfgGpRRuIE/z8DceodZbtX8AHI5wDBi6sLml0whKo5lnZRVf2fsZ2pb1uqPm0oQrzTYEPGGeTf5rsXcrr2c9nBp7rzFc52kefGs3zhU4Jz9BygR+/sAbdKjynHI9Q623arLx23L8FXp5jzrjN5CzEr5K6edibNEjCAMISCOcAoYu5HlQJ0oS6e3E0A29Bd0w77vX6JVkk6r6fOlKswwBN3ZHzmwVNxqTlNeroci937ySuHWIFbzrz6ZL5Qq8K34q7SrJVq5pKPRWTY4Z8flL6dW9dymvV0NxXvL3KK/ssNI50DCAgDTCIWDoxIr6Ulp6+CnlATBQzkn8FuWVH1F+3nSkGYaAU7NYsZDIKvL8V14sMtixxJXl0z0J06R6A5cVHrLtwqdwMIC8mIjNlep6FCjXpj2nbLQDBhCQhtMDhi7kXpjkgrW2Gn4LhhuOvUANnibl51EnyhiCpuYW2nFihvJ6MxrykCHnGhys9zm9upQmJb4pZQKn5+61Za5AJxtAHsLnPH0v77lDef0JltP23WfkHAz1jQEMICANpwYMnVhWd47eTXlceaCT5ZvxXzKGTVSfT104WkNQWJlpTHpXXV9kyT1Jg/UGFtTX0UMH5XIFPnt8IzU222t6g1MNICcJD+VKcqu47MjPqKqhIqR6q/YPgBPxxpiPT4657a4puye8mFuzl05Vpg85dwZUS96R49W9zuz1G4q8SKTJ26L83IY7gzUE3GPGufym7LldeR0xi9wbeCB/+V/Ft/ImLz16ZLGUCXwidTlV2yhXoNMMoNvrMWKB6jpiJnllPKeNCZXeqq0E4DC8FDNhwpQ9E2oGVtz5B39ABZUZyoMC6COnG9ia+ZqFwep2o5dnxdFf0ObjL9POE2/SruyZxm/yLgzzkr9r6eq7d5K+TWX1RcrPczgzGENQ01hD7x56wlIjxjn8Vqf+hrZkvmrUNyav8uQdHHiuqJXDf1yn2XD0P+Z6cY09c2ytlAn8Vsp8Oue2Rw5MJxlA3i3GyrRVfNPMbRrP0eMUMhzbuL5x8mjO7Tc74SELY+tEI19hS6u1u8nAAAJB4aWYifdPjpl4dThTwHvD2nWSsy7kvSw5eJkdlGaJgLu/cA7lV6QaSXxHKgfPA+PhGc63ZsUQNG/blF2arPx8hysDNQQ85Dtj/4Om68s3EZyi5XRVtrFl10jl5XlgfBO6N3eeJUPQPMzIO+T0/01vSzdNPrFDygR+KWk2ZddWOkZv1eT5cuav8L3dGILl3t7CqqyA6hvPSc4uPUjbhEG0ov4vO/wU1TXVWaq3ak8BOAQ/iBlz3eSYCUWBVNztWdOw36si8vCBmQl2edEI68mr69raLkg1ELwCmXf9MPvumSfsYwqC+RzJEPCNHueRNDPBLu/jy0miS+vOSJWdy8bz93hI+vV9nzfxeviskS5m4G/NO5Uolysw4Q06WCF3zFbrrZo8xYC3kDQzdvA2gWz6qt1yCeg5/vDWlhszXjL1engz/kHjBssqvVX7CsAhmLJr4kPBVNzlR35uJH5VHTR0Ia/y5YbTrMDj2ylhOdV7+oanzGog+OaAk6HyMK5Z5V2V+uu/GqID5Tic3tzbxo2dWfpxj93hM1ss2SmBd7rhFfBmDhnycODAVcKbzmXQZ/a/JpUrcHtxli31Vk3uCVt86EnT9OMRkhOliZbcOHJaF74pNevGg6c/JBWsNn1kDQYQCBgv7bntuWArLs/L4V4f1cEj3Mn76PK8FDOCDfdwxJ181xi+HSxgmNlAsGnNLN5v7AdsRtk5sbVszxE4st68w4JZuf146IwXKlk934nJho2NIKfdMKPsPOeR5z72/42E8gK6VzJX4OKCg0qm0djVAJ6tzqWZ8V82RbM5id82RklCcX755pl3vuHdjcwo+5q050y9yYUBBALG5N0TXx9NpZ0e9wUsDrGQxbWFpvVs8IT6gQ3awIBhRQPBvT4818uMHIW8tVdmSbxyXcKBg+nNaXjMmGLAjeLe3LkBzSU1m3zDxDkKzVikxD3lA4foMmrK6IHEmVImcGpOTMhzBdrRAPqyGMjP9+Nh2X15C8nbEvq9eDm1y7r0P5gSo3nUxKxUMTCAQMB4ceeESTIXH1/IqoNJuPFk+VFjyzTZoMLDb7xYI5CAYWUDUe2uNIZyzQiUHOyxGEmOA/Xm+X5mpHhZfOjHVF5fovz4eI6gGbtGsEHJKN53zXcXNtTTNw6+I2UCf5OxgdzNIy9GsEpvleRpImYlEl9w8IfiRrlA+THxkDPP6ZM9Hr7pOGvMyZbXW7WvAByCX6we80lR+bwyFZcztdthE+xw4NGz203owbjdGKLwNAeWiywUDQSbNj42M4wtp2zAXsKjZ4/erW3dRj2RN0p3U1LBGlvFAK4fPF/LjN7AA6dWXHPTUdHUTI8dWSJlAn90dClVekKT89IuBpBzfHJqH1k9eESB586FYnpBoOR58Wak5+KpOmwoZfVW7SsAB+Gl3RM+JyrfX2Qq7pq0ZwedXwYGRp60zDmiZAMIr7YMpNdvYMAIVQPBqWyWHP6J9HFyagcsDhkdWef3P3iP1qX/XloHnnTPO9KoPqahWFSTb0rqGE5M3N9wNDR30C+PrZMygQ+nzKMz7oaQ6K3aAPICCjNSWPF+53aef368OM6YriJ3nHJp12AAgaDxUsxtP5wSM+HPUo1B8g+kl93rSJ6/wnviygbHwSavBxowQtlAcEPKvcayx8sJhKvdVcr1cxobPG5aniq/8pLnllqxutdscu+MGVMQuPeq/041nCvwlexdUibwi4mzKLPG2m3CVBvA0rqzNCvha1LnnntyeaGPE9JC8Q3RO0mPSNc3XpE+ml51GEBgVJiyc8K9wgS2yVRangtxzoR5DLqwwdNIS0xIg7Are9aoh0VVNRC8Uvi12Hukjpv3ER5sX1dwcPIcPdn9VXmhB6d2cdJcTDYOvCBJdq4j92L1v8nic7DwVJKUCbw3YTollhdaduwqDSCPRsiuzp4eNynoUQ3V5NEwM9Ip8Q45wY6swQACo8Yfdk4YN3nPhGKZSstzNLBic2Ry2g1OWCpzrnm4gYcdZMqhsoHgHRhkDQmfA17FqlpPu5MT2k6Pu1/acPMOHqqPZbTkesIZDGTOAa/OH7hzyJaiTKlcgfzZrUXWJQZWcX1nFMVKp0phw13ltraH1CryzQHfKMmudubFLjyEHozeqn0E4GA8t831Txsyn5W+e+GtwpzUSxBK8p6Xb+yfJHV+OfcVD6/IlkX1EJEZQ3Q8RMSLTFTraleUhkRBAAAX2UlEQVTyDRkv1pA5xzx308otrEJFTrex4OCjUueCtys8WZ56zfdyLx735sn0Bi4qSLYkMXAor28uPy+ckW0/uAeNE5Orri+y5BEx2SHwmfFfCXikAwYQ+CtERUUtdrlcYwP9/w8+/Avtzp4lfRHzik0VOZrsTF7lJZsbb336H66ZjyRD1QaQyUN0vGpTtr7xrim46eh/Xi8YK3Rlz+vu7NlhtQ0kz13kOYwy54TTYKWd233N9/J8Pp7XJ2MCze4JDOX1zfN7t0tu6/bynjv88/3C5zrmqT4rjj4jdV54usyJ0qSA9LbSSwAOgzB+E4UBrIyIiLgl0M/0BAzuwpZNpcBz3PgCUH0R2oEppzeS7Dwk3x655gVHOxjAHnKA494VmfPDPQeBbPoe7uQJ5DyRXOZc8vDVwD1yw4U9ex7LXo+8D3b/65FX9vIK39EawHsSptFZt9u04wzV9c03pKtSfyV1LnmKQn5FmvK6YQX5Bmpb5lSp88N1NfHUqmHjPwwg0B+fEgbw29HR0WmjMYBcoXioQ3YiL891q2iw7/J9q8k9XLyBvcw5tCrxtp0MIJPnV/GQh8y5Wnr4p+Kmo0n5sagi54BcnfZbycb4C5ZtWG8nZpcmG/nXZM4V9yb27yHlHH+c62+0JnD1mVTTji8U1zcvjJFN88JTWjhNlOr6YCV9w+MrJU2gqG+Zrw656A8GEOiFMH/fFw+fiIqKSg/WAHZ0+CoTs7y+SHqy/htxk+hMdXbvd+rC5pZ2Wn9Mbssg3oA8vyLVkvKxzgP1Vs3axmrp3RyM7ZXcFcqPJdSs99TTwpTHpM7dWwe+Lm7YipUfS6h4ribP2IlB5pzxEF9Tc3Pvdza2dNBvMtaPygA+d3yTacdm9fVdWneaZkluW7nk8JPk9jYqrwehYmbJfuk5ub6bXPegeltoKQCnQJi//4qOjr6Nn4/GAA7E5T9106r0n0tVWp77dtZ9aLCvD0vwOVuR9pRcY5z4EDWfr1R9KCHHe+9fpLUZckNKMxMeJHdnsepDCRlaL9TSnCS5xMdLjz5BF9/rUH0oIUfn5Saan/IdqXO36PCjdP5KS+93/uXDD2jW6bigDeC0gj0Kz0TgqGjOpmlxn5c6Z9tzJtP7H/xJ9aGEHHXtp2lG/ANS525u8sPGNT8Q1rkKwFYQBu8+Ye5yBLMHMFYYwB+Lvz8p+BPBMvH6+ZtvvvnfAvlerkSD3TG2tHbS1sxXpSotM/HUSmpru6D8TsxKVrnLaU7it6TOE69WrGuqtbScduwB7KtvXbQlU26yPg/v5ZQlKz8Wq1lYlSmd4oR39PG0tCo/FlV0e5uMnhWZc8jTF7hXrOc7Oc4tLjwYlAHk/zfrmKy6vtPO7ZSeH74n9x1xfs4r110VKxtKpVOB8fSsUxVp1+htte8AHIbR9AD6gtfg8xh4Iqrs5GmeEBtOKwv7kycyy+Zc49Qoodhej3UeTm/V5Pq230jiK3PTcbsx4T+cVhb2Jy/UkM03NtqdB8KNvIBINokvL2QauGJzW1FWQLkCP5/wBpU1mbfNodnXN19D+/IWSl+Ph05vUq61HWjGZgBsxI+c2dqrt5VeAnAYXC7X49HR0R7BBWPHjv3XQD4TSMDwpTOR28mB582E02T9nrQbnMpA5rzsyJoess3O7W4Ae8gpN3ghjMx55cnTTti+LFDyDdSu7JnSjXG4pd2QJS/a4pRCcue1Z8V+3/ZlyRVn6HMj5Apce9bcVbBmXt+N3mZaly43n5l75HnhjWqN7UROlcYp02TrG+8I1SraDas9BRDmCDRgcHJK2RWbsxMeCovt4zhp6caMF6Uv4pGW+ZtNpxhAJq9Il00Tw8PqnAxY9bHIsraxTrrngCeiZ5UkKD8Wu5KTi8sOc3JPPic77/nOU/W19PP01YP2/O0tNT8OmnV9c9J5Xqkrcy7e2P8Ana3OVa6rHckxnzdPkG0/OBUPb+ag2kMADkYwAYO3qeHtauQaorsct79of7KhmJ8slwaBz0FG8b6Ql91JBpBppImRXHXIc+WcvH0cb8fG27JJNcZxkxy9rVuoyPWEtxuUOdecQaG07kzvd3KcS6suoU3nMoy9hHkXkXqLeqbNuL45LsmO9vB8aN7+UrWedifv2iO7UcDkmAlFvK2rah8BOBTBBgyeq8YbV8vevXA3eCjmvZnJ/Ip06fl+0+Luo4LK40rK7zQDyDTyjkkabh76jDeS+J5XfjyBko3DodObpYfCefVgpcZ5OYMlj3S8Gf+g1DlnA5VZvD/kZZe5vjnXnGwycSZvIxhOU32s5tnqPOn6NiVmQtuUnRPuVe0lAAdiNAHDjJ0HjMYp6TtUVndO+UU4Etk48Nwp2fl+vE+kyuN1ogFk8s4DK4/+Urq+DRyisyt57uLm4y9LH+/iQ0/QpT91OU5v1ax2VxqxSfb878l5J2Tze5mjvb5rGqvp3ZTHpY+Xp8VgZ57R1Ldq+ZvcmAl/finmth+q9hOAwzBaQ8A9FAcL15PsCmEecjleHKf8IhyK5fUl0ukimDwfjedyqTwWpxpAprG9Utbr0jq8deAbVFSTr/x4hiLPv5LdaYHJE/h5wrlT9VZNt9dDyw7L5fVkco9YqHa9GM31zaMab+yfJH2cvFrYST3sdiOPhnFqJhkNJsdMfP+l3RM+p9pTAA6CbAPhWyEst70Sc2vma0bQVX0h9pDv3HmRhmwWdyZP1rXDcLeTDSDTt73SCmk9eLI/r9ocaoslNfWtm5IKVkuneGHyVoTcGDtdb9Xk3iwzVmzyTS4vMrF63nMwevMWgruzZ5PsDTxfS0fP7lCuVTiQYwD3GkvWN+8vVo/5pGpfATgEZjQQPI9BdnslJk92Z0Op+kIsri2QXuzSQ1/ONXvkQAwXQ5BRFGuKUeIt6HjOl+rjKa8vpsWHfmxCfbudUk5vDDu9VdKcXHg+8hSE/9femQbZUZVhOJACywW1dGKsSTTJ3EV/YJEgoJQsAUoQxSoE2ZQSBKSwID8UCIssYQuIKIqGLSyyJJAxZB+yT0KWmZBAIENIyAYhAX5YKfxhgZZWcv3enm7oXO9N7kz3nTN9z/NUvbndt7vvnM53+pyvz/IddS/XK6212vulTUuDJQCT3o9m6Wu2vmsbNZq0DnySsb9Xt4463rVfARkhrQpCs2O1JmsaBaW6r1yE71CX2XOr7kkcDkKSg9Le9azzwiSuRnII1m5enspLh2w9eeW40vZ3dvT5Pex8773gjf+6qUcmvo9gtvMbCxvW3q6lSR1JZwhLmvWpYOf1iFG5P3trQtWTy5KtthPp9lmnBLP0XdulUfXy5hd6PeFw7JRRN7r2KyAjpFlBqAv34fYxqRQwqhSndIwvbX+3/hWz3vI7NsxNHPsqkuIlruuH8Q4bzSFQhfbH+eenYjMts6SJPn0xiF0twnrLT8OBlTSAvNI4s0azt2spvIvCvKRhsztmnxo4lWmuyFLN3ppEpSEPaQzVkRTU38ULk2/atH1Dr5YYHdt62BWu/QrICGlXEN0rZDyUSiuadOO0Y4LCSzEI037ANE5qxeuzUwgz8rEUsPetd9xO9qimRnQI0gpfEUlxB7XCi1ZCSDutavVZ8MoTqXS/RdIYNQUm98XerqVZ5OrKTct+6jVZ0tWaylKZ5faWkzZzzZ9Te9GQVBazjGDf5rcJCy/umZ2eHXWqa78CMkK9Kgh10SWObxSTxkQozMDaLSsSzzbbumNLadaaCYkX5y6XuhL708SCcjWyQ6A1ctNq4ZD04qHJFBojmHTwvlqOtNyYVkdI83nQeL99pa2R7e1SKn/kCKVZdmiVpBmr/xS0+vQ2XbLz7j27S13bXgxmzCcNMhyX4peu2jjf+f+9j9LLwaQVN9Vmq9ZRXWe1Dhjo2q+AjFDPCkItYWmEUijXLTNOKj21/IZgnclago5qbJ8cUjl93elJNvOtXBrvpy491wXF/tToDoHGJKXVRReXQsdMXfW7YFxOtda28vz2ypaVwVivu9vOSD09erHSi5Dv9natlRvaEi9XWEn3zvtJsFSYJmvUEj1AY0lXv7EoaAm/Y84pqaenUZZUzLK6w649ss+6a2zrqA+ZAAI9ot4VhMY7aWJF2oVSXAqwrGZydYdNXnlLUBDKQZzYPibo3k0jlEs1qcswK2te+uAQaBzqQ+2X183eCgaulmMFptaA+ii/Pbn8+qBr8Ldtp6c2/KGSNFu41uEQPtjbtTZufy21scPV8pteIpSnlceU15Tnnlh2Ten+RZeGwwnSfaGNS+WoXmhc/z+jbmkVqcpxQkduu7p15EjX/gRkjL6qIDo3zA26EepVULnQpBU3B2/frguFWuWLQ6AuutlrJtTVEet7HV5q7byrR0MMfLG3a2mSRc1ddBmRXpqz0Kvho1S+KYD34nWTStdMGXnV2GcOPWLAuAEHuvYlIIP0ZQWhboS/LLzIeeGWVHfOOS3oDnRdEPRUvjkEGr+nWH+u80vi/Db7tJq6fH23t2ut2rggiGXqOr8klZaFy8ISnb5Lz7Vr/wEyTl9XEBrLoMjxCrvhuqDrqdQdo7httYwD64/y0SFQi5kG7Ge1NVBdflq1AXtnQxqT/NjSK53nm95Ik0YUColZvtkQDiAkxlUFoXFME1OKGdgXuuf5H5e6tq12/tAnLTB8dQjUGqjB9a7zUe357axg4hL2zqYUlLs3MdxcSZPjksxARn0vHEBIjMsKQq2BKijlXLkuAKtJM3w1eziNOF2u5btDoLEzWkZOE3dc56tqGjdjdGnRq0+n0grju71dS63Piol6w7TkK4jUS5rQpNnM9V6nGKUvHEBITH+oIFTZKRiqlhdyXSBGUpehZnlufnuj8wc9zQKjP9jbtdSFP3P1faks7ZWW1P3W2jE+CPyKvRtL6u3QJJE01q9OSzdPHx3EkWyEF1tfhQMIielPFYRWSpi39rEg7pqrglEBdp9efkPFpbWyLhyCvfX2uzuD1t00V0roqTQzXmMUt7/zNvZucGnpQi1vmWbA8p5KL9lqlcxS9AJUWTiAkJj+WEGoRbBz47xgzcm+LBi1WsPWHZud3389C4z+aG/XUpwzTUy6u+1HfZbfNJNcA+4VQgR7+yUt0aYg4VoPuK/ym2b2Lls/gxa/BhIOICSmv1cQb2xfH6xnee+881IvFDU2RwFVFVMp6fJyWRAOwb6lcVDr33w5eBFIe5lASWMPFctPk4n6YswV9u7fUh7QijFaQvLm6cennt80kUiOplbIcX2vKH3hAEJislRBaCzNonWTSo8u/XWvuom1bNODiy8rzX7pASt4O/r1ur31KjCyZG+XUuWsinPOSw+WHm6/olfdxBpnpdUaFJT61a2dff6Sgb2zI7XMqUxqe/nhIDpCb/LbbTNPLj3VcVVp3tpHG3IIC9pbOICQmCxXEBow37X1xdKy9dODsYNaTF1x+iQtP6fKW9Hs12xqD4JQ+9DKt78CI8v2di113WkpJs0kVkWtsXvKa2rV07by29LXpgZBwt/c+ZbzmZXYO7tS3tm6Y0uwHnB717PBuL1pL/4hyGtTV90d5Le55ugpL+rlQvEHsbdfwgGExFBg+CMqCL+Evf0S9vZLOICQGAoMf0QF4Zewt1/C3n4JBxASQ4Hhj6gg/BL29kvY2y/hAEJiKDD8ERWEX8Lefgl7+yUcQEgMBYY/ooLwS9jbL2Fvv4QDCImhwPBHVBB+CXv7Jeztl3AAITEUGP6ICsIvYW+/hL39Eg4gJIYCwx9RQfgl7O2XsLdfwgGExFBg+CMqCL+Evf0S9vZLOICQGAoMf0QF4Zewt1/C3n4JBxASQ4Hhj6gg/BL29kvY2y/hAEJiKDD8ERWEX8Lefgl7+yUcQNiLYcOGjSgUCrfncrlz8vn82bVcQ4Hhj6gg/BL29kvY2y/hAMJeFIvF9kGDBn2mubm5yRzBtlquocDwR1QQfgl7+yXs7ZdwAOEj8vn8aHMAp8e+OriW6ygw/BEVhF/C3n4Je/slHED4CHP+riwUCrPNEfyhfV6Wy+W+U8t1KjB27erOTKixJTtjb3+Evf0S9vZLsnO9/QrICOb0jTUtCXcPtO1XnCYIAAAAAJJTLBaPNceu09RRpufCiR9PROfadzs0HtBlegEAAACgjoQTP+aHuwNte63TBAEAAABA/TGn70LTmHw+f22xWDzKdXoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYL8Ui8VLW1pajol/l8/nrykUCmeYbrPtoa7SBvXD7H6YfQxUsPBcLpd3nR5IF55hv+B59ofyOptnHXrDwZZZLrfMtMYyznHRl/bd0fbdRG3b5xCtMuIuiVAvtFSg2XeXabqCiLtOD6QHz7B/8Dx7wf/V2TzrkAjLMI/HHUDLRNdbprokdnynm5RBPTE7/8x1GqA+8Az7B8+zP8TrbJ51SES5A2jb95nOi+2zpnADYgXHXblc7lT7vG748OFfd50eSA+eYf/gefaHeJ3Nsw6JqNACOMHeKM6O7b/X3Nz8KTepgzpygP5pamo6xOzf6ToxkB48w17C8+wJZS2APOtQGcsMx6owMHXE1BkfJ1ClC/ii2P67fZ1uSE4V20vP5XK50+34H8JTD7TvPnCaWEgVnmG/CJ/n34e7PM8NToUuYJ516B0VHMCj9Fah7ZaWFjtUmOUudVAPrMI40Wx7pLZHjBjxNbPxAtdpgvTgGfYLnme/KHMAedahd9ibwy8tw6w3/dW2R8e+H2+Z6txwXAkhBRoQDRzWm6PZ/lZmDTYePMN+wfPsB5XqbJ51AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgGxRKBTOLBaLG03t+zs3n8/nwtVl9vT07yS5FgAAAABSxpy/C2pxAMWIESOGmRO3uzd/J8m1AAAAAJAiOIAAAAAAPecAc2zuMy2TI2Wfk83ZGawDQ4cO/aTt32/frwh1l309UMdse4Yd+5fpKtuebp9bTJfl8/lT7HOOabN9//3Y3xlox+6w7ztML9j2PfbdgeWJyeVyJ9jxbXbtP+2cn5rOtv2/V3Pyyh1ALSlm+4vtmoWmJbb/7ehY6MTtCZcdW2B6zbYvjo6H9/tAeK/LbXts2bU4gAAAAJB9zOH6njk7c6N9c3LujRZrt88HTZPCQwNDp+rG6Fy77i05TNo2R+pw2/5ATmB47Zmm16Nz7fi1cjIHhE6fbc+066+skqav2LH3W1pajtH6oNHfqES5A2jbv7C/9QltDzdsf3t0LOYAXhIdt/0P7e98I3a/k8PTD7Jr1+g+YtfiAAIAAED2MafmW6Yd5hSdPKDbOTso/FTL4IfRou1CLXJxhyp0AE8Ld+Ug7jGH7VDthI7bv2PnblLLW2z/XLXAVUuXHDk7vtU01Ry0z+3jvPIWwKNt/3m1MqoFUE5bc3Nzk45FTlz892x/vun26H4t3SfGfktO66z4tdX/JwEAAAAyhDlEJ5lz02baac7TnWpBM0foS3GHTtj+d+34f6L90AE8LnZ8j/3WV7Vd7jDJuTK9Kmct7GrutM91+0qXzjc9vq9z4g5gU1PTIXb+P+Rc1pKm8Pgk06PR/ZpWhelbErYAtlW7FgAAACCTmLP3WY190/bw4cO/LMfMvrtpwMctYifEzj1fTl+03xMHUC2A9lvnxP/2kCFDvriPdKklb6Jpl+nYaufFHUD720fob+qewsMHVUqT3efnY2leEG8BVIto/Pejc3EAAQAAoGGQA2UO06+ifbW42Xe3hMcmmJ4KDw0MnaXfxK6t6gCG4+v2xI6NNc0eEE4ise0fxMbb7UU4GWPagO5xeBdoUsjgwYM/XelcO3Zh5ADafQxSt7PGNWrfPk+vlKZonKJd16Jxi1Erp+43Pt7Qfu9y0/hK9wMAAACQWcw5Kmqcmzk/i0wrTVPUlapjcsRCJ3BFeOyjWcB2zTNhi9la+41COO5ut2b5mtM0tNAdOHl3bHyeHMhbw67fRfb5N/v9L5SnR86YHe9Si6EcNNM403/DGbuj4ucWPg4E/X5sMsrFtv9m2KV9W5Qm+91vRmkyjQlnCq83/Tz6vdisZ93rYtMj6g6PBYIO7ieaZAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Yz/AbAG6vvKrk37AAAAAElFTkSuQmCC\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Many plots done with a single one-liner\n",
|
|
"replot.plot([range(10), (np.sin, (-5, 5)), (lambda x: np.sin(x) + 4, (-10, 10), {\"linewidth\": 10}), (lambda x: np.sin(x) - 4, (-10, 10), {\"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,
|
|
"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": [
|
|
"# Another one-liner plot example\n",
|
|
"replot.plot([range(10), (np.sin, (-5, 5)), (lambda x: np.sin(x) + 4, (-10, 10), {\"linewidth\": 10}), (lambda x: np.sin(x) - 4, (-10, 10), {\"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=seaborn.color_palette(\"dark\"))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Using subplots"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Subplots are defined by `group`. You can declare a group and add figure to it using the `group` keyword in `plot` commands, as demonstrated below.\n",
|
|
"\n",
|
|
"_Note_: Groups are represented by one unicode character. \"\\_\" is the default group in which go all the plots which are not mapped onto a group. Hence, it is a reserved group symbol which cannot be used."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"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+AAAgAElEQVR4nOy9WYwdx3omaHcb82C4DQxwBQxkP1xrm37rlx43DDQGxmAGcL8N/GD4vvQAhseYHk/bV7rS1a4rXUriVtwp7hT3fd/ERdzFfae478WlimTVqX0hKZJVk39ERpysU3kyY/8jSvEB371aqDz5Z0R8+Ufkv/zBH0RERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERET8LPHWW2/902uvvfafi/7MG2+88f6bb775twlHJX/9567uLSIiwk9E3YiIiIgIF/9DIsr/nAj5yUSg/9d6fyj5M3+V/Jm58NfJ//9Z8mfXubvFiIgIzxB1IyIiImIkIBHmBUVCnoj3R4mY/2Pmz993c2cRERG+IupGREREROAoE/Lk301N+KvM39975ZVX/sTN3dlD79uj//f+X4858eTXY/Z0vj36Nez78QlP3h77f/W/PfZewtXd//T5L7DvxyP84ZNfj/1dMmcuJ5yx768//yPsG8LCz1U3TKHz/xv1F8kc+u7J22Nu9P7L6L/Bvh+f0Pf2l/8xWWcX+t8ecxj+Gvt+fEL/r8f+bcKziUZv6/1/P/+fsO8nInAI7OS/SXbyf5f5++ZXX331j8uuOzAwMOgrXlY6Bp98OGkwWUSET7+eMzjw7Cfs2/ICL2/c5c8F+GzeWuxb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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Using groups to define subplots\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.sin, (-10, 10), group=\"ç\")"
|
|
]
|
|
},
|
|
{
|
|
"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": [
|
|
"# Applying a grid on a figure, one empty subplot\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.set_grid([\"ab\"])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 20,
|
|
"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": [
|
|
"# Applying a grid on a figure, one empty subplot\n",
|
|
"# Note that if there is a single row, enclosing in a list is not mandatory\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.set_grid(\"ab\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 21,
|
|
"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": [
|
|
"# Applying a grid on a figure, default group is masked\n",
|
|
"# Note that if we do not put the default group (\"_\") in the grid,\n",
|
|
"# it will not be shown\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10))\n",
|
|
" figure.set_grid([\"a\"])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 22,
|
|
"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": [
|
|
"# Using set_grid, you can define very easily (and visually) a quite complex grid layout\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"b\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"c\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"d\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"e\")\n",
|
|
" figure.set_grid([\"aaa\",\n",
|
|
" \"bbc\",\n",
|
|
" \"dec\"])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 23,
|
|
"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": [
|
|
"# By setting the grid to False, you can ignore the groups you defined\n",
|
|
"# and plot everything in the same subplot.\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.sin, (-10, 10), group=\"ç\")\n",
|
|
" figure.set_grid(False)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 24,
|
|
"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": [
|
|
"# Forcing a grid layout\n",
|
|
"# Use auto={\"ignore_groups\": True} to put every plot in\n",
|
|
"# a different subplot, regardless of their group.\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10))\n",
|
|
" figure.plot(np.cos, (-10, 10))\n",
|
|
" figure.plot(np.cos, (-10, 10))\n",
|
|
" figure.set_grid(ignore_groups=True)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 25,
|
|
"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": [
|
|
"# Auto gridifying example\n",
|
|
"# Use ignore_groups=True to put every plot in a different subplot,\n",
|
|
"# without having to deal with groups.\n",
|
|
"# Note that ignore_groups=True will discard the groups you may have defined.\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"b\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"c\")\n",
|
|
" figure.set_grid(ignore_groups=True)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 26,
|
|
"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": [
|
|
"# Gridify example\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"b\")\n",
|
|
" figure.plot(np.cos, (-10, 10))\n",
|
|
" figure.plot(np.sin, (-10, 10))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 27,
|
|
"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"
|
|
},
|
|
{
|
|
"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+AAAgAElEQVR4nOy9R6wex5Ym2K97MItCda2eNqpavCfXvetVF1DAzKDRPZveNWpRqNr0AIVCA4NBz1Q9iU+WctSTRPLSk6L33nuJ3opO9N578pK697/eyJOTJyMj/v/+N23EiTgRV+cDjkRzmZknI+LLMOd851/9KwaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8Fg/Crx2muv/Y+XXnrpf8v7mVdeeeXNV1999W8jGxP9+q9cPRuDwfATzBsMBoMRLv7XiJT/n4jIT0YE/X9k/VD0M38T/cxc+HX0/7+Mfna9u0dkMBiegXmDwWAwRgIiYl6YR+QReb8Tkfk/Nfz8QzdPxmAwfAXzBoPBYASOIiKP/m5qZP/Q8PsHL7zwwp+7eTp76P+Xz/7PwX/+/Jvv/vnzvd3/8tlL1M/jE777l7H/1+C/jH0Q2Zre//Hhb6mfxyP85rt/HvtB1GeuRPbF/v/04f9C/UBU+LXyBrQ5tH3cB/6/z9+P/ug31M/kC/r+56cvAGcAdwCHUD+PT+j+n2Nehm8NfHP6/98//Rfq52EwYpRYyc+IVvJ/1/D71hdffPHPiq777Nmz577il1rX8+/envQ8IqnYvv90zvNnP/xI/Vhe4Jeb99V7Afth3jrqR/IGPx08NeTd/Lj1APUj5QKLI9JgizcAPnMHtHljH4A+wRD4Ye66Ie8GuITxPP62wDdGvZvo2wPfIJ+BwRGMAFDyKOcfG37/uMx1oRPVar3P29v9s97FW+KB2DdzzfP+z+bFv+7afaL0vwe/fPZP29p6nvePXxi/j57VO55/997U+Ncdp6/RPxuyVW7DJ13PB94V76Nnza7ng2+Mfz74+vjn7fe+Jfclyz8MfsiCLd4A+Dq2aveexm0ObQ99APoC9AnoG9b6XSAGHAHvY/DdKc9/3Lwv/jVwCXAK9bOh94OKbdi1+7h4H9G3pm/m6vjXvYu3kvuR558pPzACQTORR6T9cuPfR8T917Cah1+/9NJL0Y++uqXMdWGAQGdqa/PMHtaeD/5xwvPBP4x73n6r9XnHkfNqcJa9BvjlrX8GVrt0V3zUPpjxvP1p1/Of9p0QZDV/I/mzYVvVNuzcJ3b/+iYuiX/fO2+DWDhsPUTuS5Z/uEwxFLZ4A+Dr2OraclCMh3liPEBfgN9D37DV70Ix4Ah4F93bDj1/9tPPMYfA74FTqJ8N2yq14bc9apOh48iF+JsD357BNyfG3yJqX7L8w2MKhreISPv/joj5UmSLol//p+iPfhP9+lb0679o+rlPIzL/+8g+f/nll18pc21fSa5z70nxIZ+xSvzZ0+7nA6Onx3/WfvMxPgEEZN3r9ogdrlU7Y9+edfc+H4RV/VuTnrc96SJ/Pkyr2oa9s9cO+dh3nLpWeeHg2j8bnJHwgTXeAPg6ttSHPGp7+L1cFPTOXmet3wVhrV0xRwBX1O4+if3rWbVDTAgjTiF/PmSr0obtNx6JRfX70+NvDfwZfHuqLhxc+4fNGYxfGXwlOVi9x4Nv94mGPxO7OTA5xCaAkKz/TyJOpXbupvKxf8Ji8dE7don8+TCt6ipeHv+233ki/iwi88G3J4s/u/uU3J80/6g5QBc+jq32O0/Fh/ydKXF/iP/s9hPxZ+9NVX+G2u8CMeAGuTsu/euIOCReIEWcQv186H2hQhvKDQe5awwG4UY+n6yEzB0MT+AlycGH/L1p4qN9q7U+IHeKGI2eRVvQCSAUg0lM4wdO+ti9WQS9d6/eRf6MqP5WWcVfFYkxAx/PGvLnsPPj60o+ZBL3cWyp3b45Q3f7oE/EfHL1AXq/C8W6V+8UHBFxhfKvrSfmkvjd3PuW/BkxrUob9izaLEJFdh2v//ubjwWfjJ5WeuHg2j9qDmAEDh9Jrnb5nliVjpk99M/lB37MrFLXGYkk3nn4nPjAzVwzxMeOM9fFO2tZTP6MmFalDYG80xYI8s97F24m9yfNP2oO0IWPY6t3waZhH3KwtA88Vr8LxfpbFolTgogrGv3r/UIkPAC3UD8jplVpw/oC4f7QPx8j/rx25R65P2n+UXMAI3D4SHJyO76n+YMdH/Elq9U7xcd5I5HEe1Z8JT5k2w4P9fFJ1/PBN1ri7Me2x53kz4llVdpQhQ00hQgAefsaBxgyifs4tvo/nZt8sId+yNURX8njvBHHHREniMzoljgWsNE/SJCK+XblDvrnRLSybQjhIjJTvHmnDxaNVcKOXPtHzQGMwOEjyQERxZOc7V8P+7veWUmQ/8GzaAQQkvWPX6Ti/5p97EviAGtnbpA/J5aVbkNYHCQZjcOShCAOUE6OPUuSCZnEvRtbkOQAk5xRLSqQX71nGeQf9RHUfheIyRMCmR3f6F/tbBIH2LKI/DkxrWwbdh48kyQJrR32d/AN8nVyHDJ3MDyBjyTXN2XZkCy+1AG5bDsaAQRj0SQHZAlAnkDu8jX6CO8knjjvLHfMFYKVXsUXfOD7xy4Qk+OLd8h9avaPmgN04dvYgraNJzJRWw/7+7wFgkG/C8W6dh5LePPL4f497qirCHgY66ZrZduwZ2nCm18eGfZ3HSevionzlOXk/qT5R80BjMDhHcl9Ww9KbrvfPuzvaxduZ5O8JgGEYioouSHJYchRzo6E5Jd/Sf6saD6XXcUfSFbxczek/n2Pp0c5IZO4b2Orc883SQxoeqxn79z1og9EfQWr34ViMPETi8Njqf4NfDRzWNJd6Fa2DdXiMPq2DPv76BskjoeneDc5Dpk7GJ7AN5JTkg1ZRzUQywKrVRDoLBiQI43EO45dFJOcL1an+ihV/mEHlfpZ0fpDyTbsXr9XZDhuOpD6974e5YRM4r6NLRUfm7KTE/eRTftFH4n6Cla/C8X6JienKqevp/onE0FGkoxUqTaUpyqw4dCaHjutdo6ltJQnFjJ3MDyBbyQnJzlKADptQH70hRiQt/MH5EgjcVnhoHvt7nQf77fV9c48eF4MK9uGvXPW52Yy1o9y/Joch0zivo0tNclJCR0BUxn0c9ej9btQTOpjylOVZv+6k5J5vlbM0bEybdh+u1Vw5kczs/vV9FVeTo5D5g6GJ/CN5Lo3D5/kDBuQ01aKAfnNFWMCCMmkxEXn/rqe3bCjnEQ/se1eG/nzYljpY5zP56dmfyqTRznv+HWUEzKJezW2CkJHwFQ2eNRXsPpdCAb6fkrPLsM/pZ8YcQz186L5XaIN4RsSLwynr8z8GfgWxd+kaAFO7VOzf9QcwAgcvpGcitPJyfJVRz1fHTUmgJAsLZGh2UcIVs7bBQnNSh/jjBJ1o/OyfH08ygmZxH0aW4WhI2CQJQz1Xf844VcVPiLLITYmMjT7pxJoxi0kf160PlGiDeEbUhQaorKEM+KLKf2j5gBG4PCN5GSZszzFflURZFl+ssNIIvF4kvPHZJLTEKvS7CMkgMST4x35k+NQrNQxjkyOKRAIl7U9fTrKCZnEfRpbZUJHwJTgb0Em8EjiDjXJiRbOmf5FnFJ2chyKlWlDpZyQIxAuKwz5Vi4vZO5geAKvSO5JskIfNWGYjlejpa1odQkgFFMyJ02TnGYfVTWMpcUyOSFYqWOc45eGJcekmTzK8SnOKWQS92lsSTHjvNARMLUIOH7ZuN+FYj1Ltw0vc5bin5ocR1xD/cwYVqYN1YnJ6ZwTE9ARHdUiFt853yUK/6g5gBE4fCK59uuPSq20VD3cAlHXkUTiHUcuDCkBl+UjiEDHk+NJS8mfGaVPlDnGSTJ8odZp3rWUTEj0QaT2q9E/ag7QhU9jq2eJmORAG+f+3KqdmSLzVftdKAZc0CwQn+YfcEs8GTp6kfyZMaxMGw68P11MegvqIKuTKY8mxyFzB8MT+ERyHSeulDrGiY9D354sAr4fdRgRQChWT47Zk+/jgwbdKg+e29RKHeMs2Vrq468ygaetIPer0T9qDtCFT2Orb+qKUrGvnbtPiEXAkvxFwEjiDpUc86CeHJPmn6/JDrpW2IYPa7G/8C0pOvZWmcAFiYeu/aPmAEbg8Ink1PFlCSFjWdg8VbyzLAEEZD2Lt6QKGace5byXSD5EBEf93KZW6hgnZYcj9VpJrGD/mNnkfjX6R80BuvBpbEFoRBkhY7VDPjl/h3zEcIdcEDZJQ6X5p2qwL95K/9wIVtSGtfNJUYGWxYXXUkLaObGCFP5RcwAjcPhEckqLatvhwp9VRbobJFGqEkBIVo9VuV7oY//4hWJCdOku+XObWqljHCl9c79A+gZieaBW7BvjvQl0D5nEvRlbcCIQtWlc67koRute2zBJFN1+F4IBB8STnPFD6/ym+aeE5Kf6s0NuYkVtKKVvoEpQ0bXgmxTvjkbfKGq/Gv2j5gBG4PCJ5KSYb8eR84U/2y1FkdftyfyZkULiYCpAu2mHIzWWZ8665D1eIH9uUyt7jFP2yFu9x9t+lLwKmcR9GVswJppLJOb2gXenFO6QjxTuAC6NY4fnDBW/TvOvbDZ9KFbUhvDtKHvk3fl1+nuk9o+aAxiBwyeSAw2qsjtXoBNYJFw6Ukhc7HC0pO5wpMbyrN6ZWxIrJCs8xlE7HOX0y7J2Uin9o+YAXfgytqruXCmeuZzNMyOFO4ADRILU0J2rVP/kDvmoFm92yE2sqA17528Up0iHsjVnpVXlGVf+UXMAI3D4RHIqWDknsUMNyLM3C2N5RgqJg3CxKFf0RSkfy4ibhmJFbQgZi/FCYPa6UteD+Ka0WEpK/6g5QBe+jC2V3b2kXOxa7+y1hdmuI4U7gAPSdEGz/Bv4MCmzeecp+bObWlEbqtjhczeLr1fxpMGVf9QcwAgc3pBcxQFWnxRl13AcKSReO5sduJ4ay6MmRWvJn93UitoQPmxVJrsqm3r9XnLfpH/UHKALX8YWtGWV7NX6pOiYdr8LxXpnJZPdY0Mnu1n+qUnR2RKTIs+tqA3h21Flsltlg8KVf9QcwAgcvpCc2mIvW4oIjkULAvpHCol3HjgtJnQpwcppPtYuJzVPxy4gf3ZTK4zjkYlDBbpu6l3Ksk7zN5L7Jv2j5gBd+DK21FFeTvnIRlO6kTkB/SOFO1T5yCv3Svmn6o0fOEP+7KaW24Ylvh/D3mWFECVX/lFzACNw+EJyOkG2RSu4kULiebtWqT5GK1Tfjit0rTCOZ+4G8cH6ujhxCKx2/pbYTZ24hNw36R81B+jCl7HVN2Gx+DCfz5aEarTOw+cE18zLru06Urgja9cqy7+qu6k+W14bljlBarYqSYqu/KPmAEbg8IXkdNLsi2I4RgqJ5wkdZ8byeHZcoWuFcTzy45+jBznEpAzI+9PJfZP+UXOALnwZW7KaQ6EMUGJS/y1vETAiuEMuBN8ZvhDM8q8eT+lPtRxdy2vDMjHkzVb1tMGFf9QcwAgcvpCcjtBmURbXiCDxyKByRbzyPHm1tI9ZRz+hWWEczwczSpVyUgZHP29Nej4IE4bWLi/8o+YAXXgxtlo7RTWHqE3LHuVBX4knRh8OT6oq2+9CsLxQkCz/6tVyVpI/v6nltWEZFYlmq1KowJV/1BzACBy+kJwq0l6h1A6URcsTjh4JJA7W/0l2HcrMWJ5Za1KDv0Oz3DYE2Yo/jHs+OGpCJdmK/s/mifd59YEX/lFzgC58GFvtV++LSc7n88v/O1gEjGqJ+06WcPRI4A6VDDZreDJYln/AMfH7LKjHHoLltWHX1kOFOrLD3mfZUqUO/aPmAEbg8IXk1Ef5WvmPctGKbCSQuPhYTRAfqyfDd6yyfMySfwjNcuN4EgHgqqXddBYbNv2j5gBd+DC25Ee594vVlf5dUem4kcAdeXJQmf5FHBMvqv5YbVHlo+W1IXwzqp44wYKx8mLDsn/UHMAIHL6QnFLnrxCz1nH8kiD/mWsqE0Aopo6rPphRyUeV6bjan9JFWv7ntGHHmetiRT5leaVrqphKD7QAQyZxH8aWql9bMWZNCoJn1Y8eCdyRJwif51/lsApPLc9H+GbEi8Djl8tfUyXXTSX3TfpHzQGMwOEFybV21eN4Kvy72pX7uXInI4HEa+fys1YzY3kySkCFZrlxPPuFPE7PouJano3WvWGfmBxvPuCFf9QcoAsfxlb3pgOiLTfur/TvemQt8QOnK/e7UCyvJGSef8A1Iqv6FrkPJpbnY//Y+cLHq/crXRO+UfFGRcppDIV/1BzACBw+kJysQVk57qRA7mQkkHiRZEWWj7WLd8Q7bVlk/Rmt9o2cNlTyONGErtI73X1CTByX0Qdzh0ziPoytnmXbMzPk86xI7mQkcAeM/XiSE3FBFf+Aa+J3GnEPtQ8mlrvLqamSoOKxo2+WD/5RcwAjcPhAcnAMo3OUBzb49mQxkB93ViKAUKxey3NnJgmkBnPffVqY6RiC5cbxLN2m9fHvOJaEDsxKDx1w7R81B+jCh7FVP8q7VOnfKbmTpdsr97tQTJV1SznKzR1Xq5Kj469GaPzw42x5nCLrm7IsN3TAtX/UHMAIHD6QHMi46FZngIDcrIzOkUDi3Wt362U6K6X7sAu75x5VaSZz1Au70++OhkziPoyt/vF61Rmgz+RldAbPHTD+3xgfc0Da+M/NkJWarBH3kPthYJmLY53M8cSKpMdc+0fNAYzA4QPJlSnNlGVqEnBi+CQgeBIHwpGxSgfTSzPlHnNUFMj10XLjeDQyx2OTYtAZiTWu/aPmAF34MLZ0+7jK6Iz6UNV+F4QV9PHc2NoDolxiT0rpyZAsMz76xGWtzHEwn8SgQ+YOhifwgeTystWKLC+jM3gSj6xvaiICffpaJglkTpBk7crL4YpB505wNTLHY4t3R1oyd0dc+0fNAbogH1vQjiBZorPLXZDRGTp31C7n11bPza4/dS0Rg15B7oeJZfmomzkOVg/JoVdXCJk7GJ7AB5LrnbdRO+g4L5g7dBIHq+9yPcwkgcxg7miFm7U7Gorl6ZXFmeNvTtS67sBHSXzU3fQ60i79o+YAXVCPLRXnWqGea6NB34krwqSIQYfOHUW7XHn+wY563u5oKJblo27yGJhKytMIV7LhHzUHMAKHDyQH9Rjjnaqz6TV986xrZyIGveKr0gQQkhVlq+UGc3ukd6drmXE8t4UINAj66ly3cg1hi/5Rc4AuqMcWtF28UxW1pc6/H/g4EYO+/aR0vwvFimr65vpXoK4QimX5CN+KqiLQ0mpnk4TFycu88I+aAxiBwweSg0oOear8eab07uYO17sLncTVLleOPmKuTIrSu0uXugjBMmVuzt/O1Ucsst7ZiUbaUdpSeSGTOPXYAn07oXW5TuvfK727lEVA6NwBGpd5u1xF/sHuqC96d7qW5SNoo2bpIxZeU0qWfVKt+pAt/6g5gBE4fCA5dRSjQTa1czfFRGDS0tIEEIqpUmc5ZJObzedZ8XKtd5AVyG348Ve7ADur7wJg+0fNAbqgHltdO49l7v6XsbxFQOjcARqXcf/efSKz3+X5Z7Io98WyfIRvRTzxP6chdG0YeoLtHzUHMAIHOck9rInjhvem6g2CnElS6CQOR+LiuGH45LaMj6oY/Gy9SZIPluWf6eS2a0sSB7R+L7l/1BygC+qx1b1uj5jkbD2k9e9VPdiUSVLo3NE7e23uDneRf/VJUvWwHF8sy0fTyS0kDsW7o9G3i9o/ag5gBA5qkqtJTaaxmgW2c45JQyfxzq/l8XZ6FZAiH01jpHywzEBuw3JunftPJWXktpD7R80BuqAeW1ACMI5x3Z9ezq3I8srIhc4d/S35Ma5F/kFITfxuIw6i9kXXsnw0LedW156tVkbOhn/UHMAIHNQkVyTIWsZUokRTNZDQSbxrx1ExSVm1I5cEMrP57phlSfpgmYHcmlVApHWcvCr63fSV5P5Rc4AuqMdW37SVYpfrVLpEUpHlVQMJnTuKstyL/OtZuUPsju44Ru6LrqX6aFAFRFrf9ER7NuIQav+oOYAROKhJrq7JtFX7GlBDOCa7G4+KCSAg6167J7cKSKGPT7uFTtqoCeR6d7qWGcitWQJMXdcTqYuQSZx6bBVJJBVZXknAoLkD9BFHtcRjP2vcF/kHx+rx7ui6PfT+aFqaj+3XH4lx/+lc7ev2LE7UFfadIvePmgMYgYOa5Ew0maRl1WcMmsTbGo64DmQfcRX5ODA6qZTwoJ3cHx3LjOPJKXRfyh6Z7wRg+UfNAbqgHltFEklFBn0nngy0DA+RCJo77reLvv3+9Nx+l+cfHKv7ECJhYmk+mtSdl6a0Z4nVFULmDoYnoCY5jGzMLCHpoEm8rTc+niw64irM5hu7QEyUrtDGq+haln8YQs5K6iJFCNilf9QcoAvSsYWQjZknJB0yd9Su3Eviqhfk9rs8/+ohEvqhOdSW5iOGkHOe9qxr/6g5gBE4qEkOEhxMg40hRi6eRH51tJAAQjIVbJxT67Ywm0/WSv4mzGogqf6VOOIqY/Dhj9/vHbpqICGTOOXYar/zREzePtYTAo8tJ0QiZO6Ayj95VUDK+KdqJX+umZzngaX5CN8IEVe9U/u6KjlvXnZyniv/qDmAETioSS7r+LaKQYxcWrxKyCQOBtI4RUdchcHcnsSr6Fqqfw+SI67R2UdcZcz4GBnJP2oO0AXl2Mo7vq1iA6OnpUp6hMwdZeKqC/1T8lzTyP3RtTQfy8RVFxnGMTKWf9QcwAgc1CQHwbjxLsz1R9rXyJL0CJnE492JEkdcRT7m1UoOwVLjeEylgxJTiSQnLpP6R80BuqAcWx3Hk1q3M4cncFSxLEmPkLmju4TGZRn/Bv84IbNWcgiW5qOpdFB83esPOYGMMTJATXJldrmKTMWrNEnJhEziZY+4CrP5ZLWEldlSMj5bmn9Y8Uk+7I6GTOKUYwvazFQ9ACwrzjZk7qjHVWdLuJTxT9VKJgyRMLE0H1EkXDzZHQ2ZOxiegJTkkGRKIMEhLeg5ZBKvXbpb6oirMJsPIeiZ0lIDuVWG4maja2McB2H4R80BuqAcW1gyJT0L0zPtQ+aOrKS4qv6pEImIi6h90rE0H+HUIPbJRMQZKQYZwz9qDmAEDtJA7nvfipXUh1+YXStD9iBkEleB3AVHXIXZfKevi92yqSvIfdLqI2mB3DLmc+1uo2t3fXlEXGf1LlL/qDlAF5Rjq3v1ztTEr8rXifpQ2iIgZO6AsR7vcp25ntvvivyDJJKRlkCGJYsF36x4dzT6hlH6R80BjMBBGsh9OZErGLfQ7FqwInsjWpG9Pn7IiixkEldxjYu3FJLASM7mSw3kRvr4dx48IybZC812Ek39o+YAXVCOrd4Fm8Qu18GzRtfJWgSEzB0Y6gFgEFNtGi9HacN8hO9EfOLUYrxzB98sIa91j9Q/ag5gBA7SQG6EMnDSBj6YMWxFFjKJd23/utQuV6GPJURhfbY0/+A4O/4wHTL7+PtQDi5kEqccW6Zl4KTBBDJeBEQTyqJ+F4rBWC/a5Srjn9odjbiI2icda/YR7cSpzY9ycCFzB8MTkAZyH8CJ5QJLEzwOmcTLkm+hj7DqfX3888E3xgdZDi41kBvp458VO+raP2oO0AXl2FLj3SSWqy17ERAsd8jx/nr+eC/jX9lFqK/W7GMZgeyyVo8dPUPqHzUHMAIHaSC3JJg15jFYfdNWDJsUBEvibeWPX0pl8wVcDi49kHsBzvHLvTaxI/DBDFL/qDlAF5RjS+74t91vM7pOVhhKsNzxoNyOfxn/yoah+GrNPsK3IZ7sTzPf8YdvVrxA//IIqX/UHMAIHKSB3BkB2DqWdiwYLIm3lQ/ALpXN99m8JCboIblfVS01kBsrABsxJsjEP2oO0AXZ2MqI+dV6/xnHgqFyB8T9lYn5LeNf2UQ0X63ZR/g2pB3361g9Ec0sC93UP2oOYAQOSpLDDDIGnbt4Mrmjrn0VKomDlZVgKOMjKNabVluhsjT/YoFaJAmGrEoQLv2j5gBdkI0tpEowsUnB9ahPFfW7EAwyf8tk/Zfxr6wUla/W7GPXDlkGzlwT1Yfd0ZC5g+EJSDP5EGUGujcn6vcb9mUSQEhWtk5tKTmHeeb1lqlsmH+PO8TH/90pKNen3h0NmcSpxlbZXa6yNvDOFLEIeNyZ3e8CMaX7OS9f97OMfyj1lgmt2Uf4NmBVRSpTb9mFf9QcwAgcpIHc4/GERjt3nxArsmVfZhJASDb41iTxUSoow1RKzkFWBth1nNyvqjYsk+/mY/Hx/9MclOtT746GTOJUY6vsLldZ6/9kjlgERH0rq9+FYl07jwsejMZ8Ub8r9O9JV3wt4CJqv3Ss2ceeZdvFQnjPN8bXru+OLiL1j5oDGIGDNJD7oySW6655qaGOIxfEimzO+kwCCMZaO8XK+53iXa5Scg6bDoiV78b99L5VtGGZfOdviY//pKUo1y9TNcG2f9QcoAuqsYVd3aZv4hKxCDh/O7PfhWIwxuOxvvlAYb8r49/g25PFQrS1i9y3qtbsI3wb4hOn6FthfO3omxVz9EczSf2j5gBG4KAkOcxi47WzN8TEYMqyTAIIxdpvtYrV5SezS5FAkY9dcnd0+Zdoz+jsXTRn8h27KD7+s9eiXF/FjubUTbXtHzUH6IJqbKWuHG0AACAASURBVEGcb9yfkepb985aKyYGxy5l9rtQDE5A4gVNNOaL+l0Z//rHzBaL9IiTqH2ras0+9k1eJib6Z2+aX1/Gjr45kdQ/ag5gBA4yknuEG8vVfv2hmDR9Ni+TAEKx2oXbYjI7cUkpEijM5jtyXkya5q5He0ZXNiyTb+9J8fFfsg3l+mmxo679o+YAXVCNLcxYLrCeJVvFpCnqW1n9LhQru8tV1j+1O3rhNtozurJmH/s/nSsms9cfoVy/HjvaQeYfNQcwAgdZIPeNR2LCFg1KlGs+rIkJ5XvTMgkgFIOdiHjCNqt4l6tUNl/K7mgoNiyTb+sh8fFfhyO/APFA8YRy6XYy/6g5QBdUY6tn6Ta0WC4w6EvxLnDUt7L6XShWdperrH+9s9aICeXxS2jP6MqafRx4bypqxj/EIccTyhs4E0od/6g5gBE4qEgOCCqelExGmpTE2mBDFfBDJfEqu1ylsvmuI0+2HdqwTD5ZBxhJgLXjqDxSXkfmHzUH6IJqbMHxvziyvYhyvbR6wKFyh9rlKpiUlPUvbXc0FBvio9T8fANP87Nv8lIx2T6HcKSs6R81BzACB1kmX0rShqmpGpj324cTgAeEVNbULtf6vaVIoNBHedzesDsaig0L5EYuwVQ7h5tUouMfNQfogmpsQVuJpI1bKNdTJSkX1ktShsodapfrUf6xZFn/1O4ogli/axvi4/22UhVSqljvnHViIXIUZyGi4x81BzACB1kmnzp6w4nlAgNdsHj1e/XBcALwgJDKmtrl+upoKRIo9BFWv6Na0MSTXdqwQO4Zq9C0I+PrE++OhkziVGOr7C5XWYO+FC8Cor6V1e+CMFXZZkLhz5b1L213NBRr9LH96n1U7UgwOKGh3B0NmTsYnoAsk0+W0kGK5QIDXbB4cnDm+jACoCajKgalimJiOXi28GfL+qhqp94zq53q2oYFco9fKHZ/LptrR8aGWVVC0z9qDtAF1djCrt6iNN3G1zXdQuSOrLJ2Wf2ujH+dB8+Ik5qG3dFQrNHHjtO42pFgUAaOcnc0ZO5geAKyTD5ZB3j712jXbK54ESKJg/VNT3a5Tl0rRQJlfOwfu0BMnKKVMLV/VWxYILeskIKgHRkb7Jq8Ph41Nqiqf9QcoAuSsZUS62vcBneGa7qFyB21K8ku17iFpfpdGf86Tl4dtjsaijX6WLZCShWr1wPeTeYfNQcwAgdZJp8MLt53Cu+aTRUvQiRxMCDweLJ25V4pEijjY9+0laUnlT5Zs3+gu1WmQkoVG3i3XNyULf+oOUAXJGNLxbNOxbtmSsWLELkDxnY8WZu+slS/K+Nf7fK90pNK36zRx7IVUqpYPVlvK5l/1BzACBwjJZMPrHtTooK/af8wAqAmoypWZZertJzDfNqKF7o2xL/W5EP99mTUe6SVAnPpHzUH6IJibGGXApTWXPEiRO6oUiGlrH8+VLzQ7isNPqoKKZvyK6RUMVYQYAQPskw+qVeFmEIPO3+Nq7wQSRysbB3gKj6GWg94SCC3rJAyprhCShXrm7BY9MWLd0j8o+YAXVCMrSoi6VVsYMwssQi43Tqs31GPgbLWzH9F/a6Uf3J39O3w6gE3+ghVkLD5T0mZEemrhswdDE9Alsn32TxBuNceol0TYv9EnMeGYQRATUalLZr0NR9HFZFAGR+xqye4skb/1Mc/mrBh3qP3i9WomcVV/aPmAF1QjK2OEyJjt3fmGtTrNi8CQuQOVdWmRM3vKv7ZCLtwYY0+9s4dGh+Ocv1rD9Azi6v6R80BjMBBlsnXpNmHYZD925jpFSKJq0y+j4oz+ar4CJIyQs5hJ7mPld5HYybf8ctWPv5KW/AgjrZgVf+oOUAXFGML9B+bNftQ+sDMpOLFicvD+h31GChrPasS+agdSPJRiUFWcbxYj7iJ2scq1uhj35TlYoJ/5gbePaS24AczyPyj5gBG4KAiOdCqwtalA/2/xhVZiCRek3pVYxeUJoEyPiqx20VhyTkMyeTbd0r4sBg36Lpn1Y7SH04b/lFzgC4oxpZcyMBkB7UPLN4iFgH7Tw3rd9RjoLQPFUTSq/jXP1bqq4arIKA0Yq89wLuH1F38Y7Huoi3/qDmAEThISO5xp1g5vTMF97r32oboYIVI4rBCraJXVVrO4YSd3TPbNiSTT4rSrsEVpe3efKD00ZkN/6g5QBcUY0uFMmzGDWWAPtVYYjBE7qjvYhaHMlTxz8rumQNr9FHpoN7H1UGFb5hIHuok8Y+aAxiBgySTz1IwP8SoDEL83JsThxEANRmVtaol8krLOZy3Ezxvva80ZvKt3ys+0lsPod6jSvC8Df+oOUAXFGPLRjB/3Aeayi+GyB0wtuOJ2oXbpfpdWf+Ai+KJZcRN1D5WsUYfYZcOvg3YWp/NyUOu/aPmAEbgIMnku3hHTABbcIP5wZScw5OuIEm8XiJve2kSKOMjlM2iLHmma0My+ZaJjz+8I9R3XkE+w4Z/1BygC4qxBUK+NuSMOnefEOMummA29zvqMVDWQBqnrJxRFf+gXCdlyTNdUz4+sSMfFb/zlkVi0n0JqTJRRf+oOYAROEgy+Syqyzdq6IVI4lVL5JX28WEtKXk2jdzHKjYkk28efiYfWF1A1321g5BJnGJsgcixDUHzuoLAxmH9jnoMlLWB98qXyKviH3XJM12TPtakluHHs9DvoWqTR980Cv+oOYAROEgy+Q6dFWS7YBP6tetVNO4HSeJVS+SV9pG45JmuDcnkk9VMTuN+/KGucLw72lAL1qV/1BygC4qxVa8FXVwlp4o1V9EIjjsqlsir4l+95Ble3XYXpiaAV+xVM1EC+4eK67bb8I+aAxiBgySTb+cxcdyycgf6tfumrRCThDPXwyPxtoYSeSWPWyrJORCWPNO1IZl8lj7+7XeeWNshKOMfNQfogmJsQRvFO/x3kGpBJ9a8CAiOOyqWyKviX73k2TZ6PyuY9FHJg00rLpFX1ZTA/k73AvshcwfDE5Bk8jWVbMM0KfjZceR8eCQOzz9nnXj+o+VK5FWSc5Alz265D1jWtSGZfJY+/rZKzJX1j5oDdEExthpjfFHboWkREBp3VC2RV8U/VfKsZGKaLyZ97DwytEAAptkoMVfFP2oOYDjAK6+88uarr776t5GNiX79V1k/99prr/2H6H//5oUXXvjzl19++ZUy1ybJ5FuZ6K7tPIZ/7WXbVaJAaCQOBmWF4l2us+UkFyrJORCWPNO1IZl8TfVaMU1lCTqudmCTxG3yBsD52GrK8ke11qHSVKFxR9UqOVX8U9JUU5aT+1nFpI9dMrFu2Zfo9+jaYe80q4x/KETB8BcRcf9NRNBz4dfR//8yIvP1WT8b/d3Z6GdqkW188cUXf1vm+iSZfAs2WYubgOQJGbAcGomDVRUsrSTnQFjyTNeUf2094uNvSXRV6YTdw9UJK+MfFlc0wjZvAFyPLVUl58NyVXKqWrwISMTpQ+MOGNPxLlc0xsv2u7L+KYH9sTQlz7T7S+Jj97ahEj+Y1nnQXjx7Gf8wuILhMSJSfici83+Sv4/I+mHOz/73qtcnyeSzmDkFyRMiYHl3cCQOVlWwtNIEUE68D7oPWNY15d+Ddqtll9TE+ypipYCS/ulyQx5s8wbA+QRQVcmxMxFR5SmjvhYad0AZw3giUrJEXiX/mgT2QzHpY0/FxLoqJifeNhQtyvinM24ZASEi7qmR/UPD7x/AUU3az0ZE/vnLL7/8X6P/v/273/3u35e5fpwlVROdyZVJ7aSOS3fQr921X5QL612yNfaLwj8Tg+Mt2Olq/7a71M9X8VGVPNt5jNzPsib967jxUHz8P5tn5T6y2kHH2RvO/cPiikbY5g2A67EFbSOq5Cy3cn3oW3GIRNTXQuMOlVgXjfGy/a60f9/Wj96p/axi0sfeJLEOvg3Y94BvWMxLExaT+IfBFQyPEZHyjGgl/3cNv2998cUX/yzjx38D//ntb3/7byPCP1bm+s8J8P1nc+NB86yrF/3aP1++FV/7h8Wb0K9tG89++jl+9u/enWLl+j/tFnVU4f+h4Zd7onrMD1+stHL9HxaLOqrQf1wDgSaGwTZvAFy/p58v3RR9YMlmK9f/YYaQGfrlfquV69vET7vk2D5m5frfJSXPgKNCww+LxMnHz1duo1/7WWdPfG34plHAkCYYviM5yvnHht8/Tvu5aAX/36K/m5D89l9HRD5Q5vrQiVyvcgcTMmlv7cRfkZ2rByyHtopvFCytsgos62PVXQIfTPrXdeKSaNfZa63cR1Y76Np30rl/CDQxDLZ5A+B6bHXtlcH8261cv2/WWhEiEfW10LhDJdbtOl6631Xxb+BjIbBfSwT2QzDpY3+SWNdx7ib+fVoT+Z1o0U7hnyFNMHxHRM5/Dat5+PVLL70U8fOrW+DXEbm/3PhzEZH/5+jv/yP8+ve///2/i35uV5nrwwCBzuQsdgEES/8w7vngKDvB/I0By+CXc/8MDPTthBZZecHSKj5SBixrt2fiX9cBcbTfs3irlfs0Jg+59g+bMwC2eQPgemxVrZJT1XoWbxETwP2ng+OOqol1Vf2rC+zjanDaNOlj1cS6qjY4qkUlD7n2D5MzGJ4iIu1PIzL/+yRWB2QafhMR9a3oz/+i6ef+CVb90d997G0W8P0kmP/96Xau3xCwHBqJQ4WLqoKlVXysminog0n/ur88Ij7+a3ZZuU+92sFu5/5ZIY1/ZZc3AK7HVtUqOZWvv3qXuH7U10LjjqqJdVX9UwL7p6+T+1rWpI9VE+uqWmPykGv/0EmD8euCa5Jrv1YP5rdyj6fdQtQ3CVgOicSb65GWJYGyPoL+XxWtMB9MTQA37BUf562H7Lx7Ve3Azg5jnn/UHKAL12NLVcnZd8rK9bu2HBSLgA37guOO/pZqGp9V/bNVh9umSR9lYp0tjU+ZPNR+/aFz/6g5gBE4XJNc7awI5O6bvMzaPQbfniQG5NOuoEi8a/cJMQlZXl6wtAqRQwWQePL9yWxyX6v6B+8k/gBF78jGfVS1g9nrnPtHzQG6cD22emeLGL2OY+Wq5FS1xvEX3ARwzOxKVX6q+gciyjbHnw0D32Rinc0qP32Tl4rJ97mbzv2j5gBG4HBNcvUP7Vpr9xj4KAlYvvc0KBJv3IGoQgKlfZT1Qt+dSu5rVf9U0XVLOxAuFiZZ/lFzgC5cjy3bH9rOw+cEN0V9LbQJICQhxMeQj8vV+a7qH4go29yBt2HxBLC3X3Be9E2wdZ/eWXYXJnn+UXMAI3C4Jjk4vrF91KYClq/eD4rEG2OQqpBAaR8hAeeNlueDr493HrCsa9K/vulCoqPj1DU795GhCZ+7rXYQMom7Hlu2j9qgb8WLgOmrwpoAqsS6lkr9rop/XZZjcG0Y+PbL05oY1+PKJ9ZVNUhMsxmakOcfNQcwAofzTL6GSh227tE3NQlYPnM9HBJvG5qFWIUEqvg4MHqa2Cl4WCP3t4p/kBkdT+ov37Vzr/t2K43k+UfNAbpwPbZsB9vXLt1NsvAXhTUBlFVyRpdPrKvqX+d+u1n4NiyeAN5+mCTWrbB2H5gU20xOyvOPmgMYgcN5Jp8DuY3euevFROrohXBIHJ571hoxcT1+uRIJVPGx/1Mhwt1+4xG5v1X8GxgzSzz3nSd27iV3USzVGs7zj5oDdOF6bIF0lE25jfbbT8REasysoCaA7dcfiYlrNLar9Lsq/nUcFzqccNxJ7W8VH3++KHRhe+dusHYfOBa3KU+U5x81BzACh/NMvkRwt3PPNxbvsV1MMvd+EwyJg/VNSmKczt+qRAKV5BzUPW6T+1vFPyke3tbaae1eAw7ukeYfNQfowunYetypBHet3+OdKUFNAIEv4l2uaGxX6XdV/KudS+4xufw9qA18++nEBSUebus+8C2L77HU3j2y/KPmAEbgcJ7JN0fsznUcuWDtHnKXsXv74WBIHExnd66ynMPM6ruMlBYHcv/yzMnunNplvF0ukxLLP2oO0IXLsaUy2MfYzWCXu4ztbT3BcEd9d25NpX5XxT+1y2hLvstGn4EJ4H4xOYMkFmvv/4iYZMK3zbV/1BzACBzOM/mmLBc7UGduWLuHjDPsWbs7GBIH04lxqiznsCiJMzxQPs6Q0uIJ4MB3dsXDE+tvWST65iVLcYYZ/lFzgC5cji2pYQl6dzbvI8dg+8P2YLgDYoZFfN6WSv2ukn8PLAv4WzDw7cftB63H58G3LN4djb5trv2j5gBG4HCeySfL8ly9b+0eUtS3d+m2YEgcTKekUGU5h9U7BSF+dZTc37L+/dLe6WT3oWo1BSz/qDlAFy7HlqxiA21k8z4y07h241Ew3KEydFeXz9CtPAG0XMLThsUTwLU7rWfogtpEzE9jWUGAERicZ/IlZXna731r7R5Ka3DO+mBIXDfGqfIEUENrkNLiCeD9VifxR1XrqWL5R80BunA5tlzVsZYxsh0XbgXDHTCW40VdNLar9Luq/qkY2cfuYmRNDHz7YbEY0/BNsHaf6FsWc/eHXzj3j5oDGIHDeSaf5bI8YGpLfuryYEhct0pHZT2vXccrVxshfS+QyXf1jpMMxJ6VO8SHdOdxp/5Rc4AuXI6trp3HRL+N2sjmfWQmfueJy8Fwh6yS01WhSofOBFBVG3EYI2ti8QRwptjVr521F3LUWH7UtX/UHMAIHE5J7kmX9bI88cC4+kBtyYdC4kqDrGKMU2U9r4ZqB9Q+l/Xv51OXK8c46Vj3pv1id3TTAaf+UXOALlyOLVdtI2Nkuw6cDoY7oHZ41So5WhNAghhZEwPfvm8R+qHt1x5YvZcsPwrfOJf+UXMAI3A4zeS7k+hsfTzL7n0atuRDIXGIO9OJcaqs56WqHawk97msfz8dOl05xknHXO0yNftHzQG6cDm2XO3OyhjZ7q+OBsMdfdOqV8nRmQBSxMiaGPj23ceiLGjbvTar95LlR9vvPHXqHzUHMAKH00y+y1Jp315Zntjklvxbk4IhcYg704lxqqzndble7YDa57L+/bTj68oxTi7bwNQ/ag7Qhcux5So+U8XIbtwXDHfUq+Tcq9Tvqvqn6nEfPkfuc1kfv3sr2ZmzGHIUt8G46m2A4R81BzACh9NMPoe7T4PJwH/2889BkDjsbOjsPlXW87rtZhcWy+JMvg17Ksc46ZirTNNm/6g5QBcuucPV7pOKkV3xVTATQBjLVavk6EwA4Z3E43CXuxhZE2t/KkOOJlm/l84urLF/AXMHwxM4zeST8Wfz7MefyS35Z30DQZA4xDaJnYf9lUmgUhu2djqJw8SyOJB7+TYnOw+utOaa/aPmAF245A5X8WeKoxZsDGYCCGNZVLApH3+mMwEEboo5arO7GFkTq917mix2Z1q/V++8Dc53R0PmDoYncJrJ5zADtX/sgvhevzytBUHiPauSGKcdxyqTQNU2hIoacSa2pZqqmBZPAOesdbK6dlVtotk/ag7QhUvucFWlpTEWN4gJ4NPueCxXrZKjwxtdO44K/l61k97vEqb0+cZZDjlqa8jEdrg7GjJ3MDyB00y+ze406PqmrhATwDuP/CfxyHoXbhYryIPVYpy09LwSLca2+3YDozEszuSbvNRN9qGLerMp/lFzgC6cTgAd1WmuZ+MvCmMCeK9N9NloTFftd1X96zx4RkwAI64i97uEdZy5Libz01ZYv5fUYuy2HKfc3IbUHMAIHE4z+Va5q0Ihaw7/fOmm/yQOz/vFarHL9c2VyiRQWc4hqXbQfu0hud9l/Pv+0znJ7k/5GCddk7VgXe2OhkzizrhDVqGwXAs6bo/bYhd4YMzsICaAIG8ST1g/r1aFQoc3Ok6IGFmoJ07tdxnrPJrU6J1rv0YvfNOEUoG73dGQuYPhCZxOAOUu14Ez9u+1dLuYAH5z0XsSB+ubsFjscl28U5kEKss5TF6WiKPeJPe7jH/fvTfVWQUCnXrMpv5Rc4AunHHH/XatXS4ta9gFDmECCALH8S7XlGWV+11V/2oXbot7TVxC7ncZ69r7jdixXLbd+r2gtnp8r0XudkdD5g6GJ3Aq5SB3uU5U2+XSse51InP0pwPfeE/iYP1/Sna5bj6uTAKV5RxmJzF1x+yVR8Ky9rae5985rEGqdkevu9kdDZnEXXEH7FTr7HLpmqzJ/ezZM++5Q5W9nL2ucr+r2n7ATXE7RFxF7XcZ6952WEzK1u+x3w4nLjvfHQ2ZOxiewKmUg9zlilaStu/VlQz+H7885D2Jgw3IXa5HHZVJoLKcw5KtYifWYoF0LGt/mOz+vD/dyf3U7ug5N7ujIZO4K+6AnWqdXS5dGxgtdoGfDX7vPXd07j0pJjnRmK7a7yq3X8RN8Vh8bxq532WsZ+1ucSy7/Wvr96LYHQ2ZOxiewKmUg9zluvHI+r0kMf64bpf3JB7HOL0+/vngG+Mrx55pyTms2SViMR0Qo6nVor4S7zp8Ns/J/dTu6PFLTu4XMom74o6OY5eSXS67taCl9X86VySQ1bq85w4Yw/EkJ5rsVO13ldvPgKcorHepkI/q2nfS+r3aJU9FfceVfyFzB8MTOM3kG+0uvkoejfywZLP3JN72sCZW1qOrr6y15By2HhIfjXX2j0aM2/HCLbGynrTUyf1kLViI6XFxv5BJ3BV3dO5P4qss14KWBn0tngA+eOI9d8hQFzjxqNrvdNoPdv90TiooTCYCdroIdXng9qRCtiE1BzACh8sJoMsMy9oZERz9w8zV3pO4SWyNlpzDHnfB0abWeULs/vTNchNbozLVd9jPVJftR80BunDFHa4zLCGOK04gu3bHe+6QyW4wpqv2O532041VprC+KcvFbv65G/bvB7ujGnqMJhYydzA8gbMJYKssy+OmAkV7IgL6/YRF3pO4SfyIlpzDkfPO5BFMrSvJrut1tPujKrJsclPtIGQSd8Ud3ZvcVqCATM54AnjmivfcIXe5Oo5cqNzvdNoPOMpVHLep9Y+dL5712gMn91MVWZ6Ur8hiYiFzB8MTOMvku5uU5fnIflme+H73vhUTwDGzvCdxE30trQng6UQgdap9gVRT6052f3oc7f64rnYQMom74g7dKjn69xO7wD99fcZ77pCC9yB6XLXf6bSfrl4phQ18+IXYrbz/rZv7fZTcL/rWubhfyNzB8ATOMvlkWZ6xC9wQwNPu+H7fRasy30kcdBF1Ffa19LyuOG4LA+ve6FZhv67ntcXJ/UImcWcTwEXu9EPjPpdULPpp1xHvuUOWvIQxXbXf6bSf0nI96KYtTGzwrUliQvZtt6O2EDuOcPrk4n4hcwfDE7iTcpCCpctHLAHoGuxsiF2nHVokUFnP647b3VgT61nxldj92e2mxiZk/8a7sbPcZJyGTOKuuKN31pokM/uykzaRNct/3LTX+wkgjGGdXSftCeDKZDd2p5vdWG17IkKOvnvH3QYAyBS5FNgPmTsYnsCdlIMULHXzYQVTW/L33BwB6BrENsW7XBv3a5FA5TZsTaodvOOu5q2u9c7fKHYcDp9zcj/XmnMhk7gr7nCtzdh56KxIIFu+zfsJoIo7a60Wd6Y7AQSOEvGY7mre6pgMOfr+k9nuCh3MkgL7LCHFCATupBxOOZVyAFPHI9fcbMnrGmQ3xqtqjRrJukQuqx34rufVN2OVmACeuurkfu1Xk9qqY91UnQiZxF1xB1QAiRdyjoL5O05eFRPAuev8ngDKGskaVXJ0eaOekb2L3v8ckyFH309c7K7UqZSQ2s8SUoxAMFKlHMD6piYyAGcdyACYEMdifeLQ1vManeh5PayR+59n/S2LRBtevuvkfjJ5CHaPndwvYBJ3xR0qmN/RTn7t0l0xeZiyzO8JoNSeG11de06XN+oL+WqVR1ybkgGb5U4GjCWkGMHBmZSDPDpwJK8BBjInzoRATZ5z9rrk6KD6c2rreX0Shp7XwJjZYhf3Tqubez5xLFcUMIm74o7Btye5lde41SomgJ/N9XoC6Fo/FEzVHp5TrfawawNZHFEIYIuzNlRyRZuqh/JotX/A3MHwBM4y+Va6lXIAc1kKyMSkYGlNY6dSewLYktRlvniH3P88G3h3ipiotrqrPABiriDq6uJ4PGQSd8IdUmD3zYnu+l1S8/a70dO8ngDC2I3jVScs1up3Ou0nd9ZcJvPpGEUp0LqEVPVkPh0LmTsYnsDZBHChWymH+J6yGPiXfte8lbGKOvIB2oKu00VsHcQ7UfufaUnt0e/eaHne3uYuVhHKOcU7Tg5KFoZM4k64435yzPnBDIJ+N95pv6tqMlYR4mR1+p3WBNC1nJemyRrJP24/5GwCWJeQqi7npWMhcwfDE7iXcnCTIQXWvVXoeXVv2OecgKqYrpSDJAEtQdd5G8SE/Ovz5P5nmtyJiSZkLndioKB73B43Hlm/V8gk7oI7oA3iCUfUJi773sC7U53vPFc1yIyPj2PnbdTqdzrtpySkPp5F7n+eda/fK7Qc951wxh2Q/csSUoyg4E7KYalTKQcw0I6LV2QrvnJOQFXMpISQtp7XMr0aoi6NKhbLZbmrkEncBXeYlEk0sYExs9zGnmpY5+4Tgt+WfanV77TaLynp6buEVM/yL8UE8Nh5Z9yhJKQms4QUIxCMVCkHsM7DQs+rd8Em5wRU2qSUg2YRcW09r3V7RHzktsP07yDDVDZmtHhwOQF0We4qZBJ3wR3QBvEYjtrEZd/rH7/Qafa5jsHYjU84orGs0+902w9kZ3yXkJL6oT+fv+6MO5SE1OcsIcUIBCNVygGsM/l49M10+/GoZA9r2lIOkgS09LwMPh6urOP0NZHJN3ut2wmgQ/HpkEncBXdIUWbXi7i+aXo1dl1a91r9RZzJBDAECSm5iPv5xj13E0BV754lpBiBwJmUw1tupRzAOi6K46N+x8dHlQaxgZSDJAEtPa893yTHR9vJ30Fm+x0571zKAUweH3XtPmG//QMmcRfcIcuyuQ7jUBJSRy847/el++lS/TAOkwkgJzRzTQAAIABJREFUcJXvElIyjOOXh0/dcYeSkJrk5H4hcwfDEziZAD7tFgPDpZRDZLWbNAHklZ7RQMpBkoDWBPDr89oB5K5MTlJdSjmAyQDyrq2HrN8rZBJ3MgHcQpPIFYKElEkil8kEELjKdwkpmcj1S0e3U+5gCSlGUBixUg4wQB7Q3LeKmUg5SBLQEnSV952ud18XRiHl0Hjf7rW7rd8rZBJ3wR3diZQTtInLvheChFTf9JXimPrUNa1+pz0BlBJSGvd1ZVLK6dngd065gyWkGEHBiZTDdZqdONDw+u4P7nceq5iScpivtxOnreeV7DyCIDT1O8gyCimHuE0SEdmepdus3ytkEnfBHT1LxE4ctInTvqckpPY67/dlTZZJhGQpnX6n235wauC7hJTciXv2yzOWkGIwsuBEyuE8jZQD+PXdO/oSKy5MSTksry7lIH3U0vMyjD10YRRSDmCyjBTEgdm+V8gk7oI7eueIWDxoE5d9ry4hpTcuXZgq53irulSNyQQQZGe8lpBqKOfoKsZdGktIMYLCSJZyAL++T/S8XGYfVzHTbFxtIlfZx9PI30GWUUg5gMns475pK63fK2QSd8EdKhv3tNts3BAkpAbe08/GNZkA+i4hBVwvs3FdTwBZQooRFEaylEM8AWxZ6Fx/sIqZSDlIH7XaUOoPjmohfwdZBnGRrqUcwGqXhf5g//hF1u8VMom74A6px1e7fM9p31MSUo4XrVVs8I0WbT0+kwmg7xJSSo9v7Hz3E0ApIRV986z7GTB3MDzBSJZyAL9++GKl8wokVcxEykH6qK3n9c4UsYPQ2kn+HtJMZhs6lXKAd3pbVCDpHzPb/r0CJnEX3CErcrTffuK073kvIRWNWZOKHCa84buElKrIMWWZ8wmgkpCKvnm27xUydzA8wUiWcogngAvEisxlDeIqZlqT12gCKGsQ36leg9iFSb0x11IOsgYx1IO1fa+QSdzJBPDdZJHy2G1NXt8lpNrvPBF9VLMmr9EE0HMJKVmTt2/WWucTQJaQYgQFJ1IOa3aRSDmAXz+uSgKWD5xxTkRlzETKQfqoLeg6doHYHb1yn/w9pBmVlEN8PP76+OeDb4y3rucVMolb5w6H7TCsXaSE1Pt6FXpsW+3KPTFBHbdQu9/pth9wlc8SUp0HTosJ6uItzieALCHFCApupBy2kkg5xBPAzfvE5HPHMedEVMZMpBykj9p6XlOWi3ufuUH+HtKMSsoBDHb/XOw8hUzi1rlD7sS+N9V531MSUpo1um0bjNl4EjZ1hXa/020/WaPbVwmprh1HxRH16p3OJ4BKQmoJS0gxAsBIlnIAv37aJcige9MB50RUxkykHKSP2npes9eJdjl6kfw9DDNCKQeweuyZXrtUaT9qDtCF7XaBMeEqFjOtXXyWkIIxG+9yzVmn7Z9u+/kuIdW9aX/C+fudcwdLSDGCghMph6k0Ug7xBPDrM4IMotWgayIqY0rK4ZHeTpORntfiZGd23yny9zDMr4bC6hQTQFfZpyGTuO12cZmNndYuPktIwZgVO01btf3Tbj/PJaR6Vu1MTn2Oup8AKgkpvZ3Zqm1IzQGMwOFEymEcjZQD+PXz6cuCKBdvcU5EZSyWcnhdP8bJSM9rdRKb+dVR8vcwzK+r98mkHMBc6c+FTOK228WlHmNauygJqav+SUh1fXlELGzX7NL2T7v9PJeQ6lm0RfDagdPOuaO+aNGLzazahtQcwAgcI1nKIZ4AXhFyDr2z1zonokIzlHKQPmpPADcfEB+Rjfvp30WT1c7eIJNyAHMVthAyiVufAB457+w4La1dlITUWf8kpEBRIR67mw9q+2fSfj5LSPXOWitONo5fcs4dLCHFCAojWcoB/Prl7uNkIrHcOREVPp+hlIP0UVvQdecxsTu6cgf5u2g2SikHMFc1aEMmcdvt4rImc1q7+CwhBZqq8S7XTj29OeMJ4MezvJWQgkVj3G7nbrrnDpaQYoSEES3lABPAb2vJUeICEjLKM1MpB+mjtp7XQREf2bNwM/m7GPZs++mkHMBAxsGFdFHIJG67XVxKaqS1S11C6rTz+xdZbzRm42c7qFdxwnQCqMJ6PJSQgrCR+NmuPXDPHfJ7ZxDWU6UNqTmAEThGtJRD5Nez3v4kmWAmCRnlmamUg/RRW8/ruIiP7J25hvxdNBvEJVJJOcT3l+Ll6/davU/IJG67XVyK6qa1S11Cyr8YWRiz8S7Xicva/pm0n88SUpA4Fj/bvac0CgIsIcUIBSNdyuHZTz8rORHX9y+yupSDfoyTkZ7XuVtiAjppKfm7aDZKKQcwV+ULQyZx2+2iymrtPuG8//kuIQVjNp7knL+l7Z9J+4H8jK8SUsD18fH00y6WkGIw8mBdyuESrZQDIBYU1iyabtNMpRwafdTS87r2ULTN5/PJ30Wz9azaQSblELfNobNicr5gk9X7hEzittuld76Iwes8fM55/2uUkAJZEdf3L7L+z+aJScb1h9r+mbSftxJScAT7L0LA29RH7bZRElJ64v5V2pCaAxiBY6RLOQAGRouSYm0P2t0TUo6ZSjk0+qg1Abz3rTge//AL8nfRbD2LNpNJOYB1fHNFTAC/WG31PiGTuO126ZuxSuwynbzqvP8NkZBatMX5/Yts4IMZgtPutWn7Z9J+3kpINZTwo5oAsoQUIxi4k3LY4JwMJAGAYn28Wr752D0h5ZiSctiiJ+XQ6KNWGz7tFsfjb00ifxfNRinlAFa7IOSD+iYusXqfkEnc+gQwevfxTkrUFq77n+8SUoNvThQTwGgM6/pnNAHcfNBLCan2G4/Eqcanc8kmgCBbxBJSjCBgXcphzzekUg7xBHDCYvEhuXjH+TPkmamUQ6OPum1o+iGxZX2TCaUc2oZ+SKzeJ2ASt90u8O7jhVvUFq7731AJqWXO759rCAs3U97wVUKqceFGNQFkCSlGMBjpUg4AyqOkPDOVcmj0UVvPSx4l3dc7SrJlEJdIJuUA1nCUZPM+IZO47XaBd08VujFUQsqzGNl7baJvRmPXxD+T9vNVQkqGbgDnU00AWUKKEQxGupQDgDKYPM/qUg5XjH3U1vMyDCa3ZdRSDiqY/M2JVu8TMonbbpc4eQsmgATJWz5LSKnkrWjsmvhn0n4gP+OjhBRwfPxcEedTTQDhW8cSUowgMNKlHADyGToJniHPTKUcGn3U1vNSz+A+zirPBt+eRCrl0PgMbU+6rN0jZBK32i7RO6eUb/JZQgr4wlS+yZQ3fJWQgu9MvDMZcT7ZBFBKSEXPYPM+IXMHwxOMdCmHeAK4fg/ZLmSeYey+Get5fbHaeBcS3TyQcgCTu5CQLW3rHiGTuM12ab/7lHT3bYiEFNEuZJZh7L6ZjitfJaQad9+ouIMlpBjBYKRLOQC6tx9O4hD3OH+GPMOIvzOeAEYkZRqHiG4eSDmAyTjE9qsPrN0jZBK3OgG8ep80/s5nCSkZf9drEH9nPK5kHKJnElKN8XdU3MESUoxgYH0CKDNwiaQcAF17ZSbydufPkGcYGbjGgq4yE3mXfiYyert5IOUAJjORa+du2vM1YBK32S61szdJM3CHSUgRZCJnGagGmGbgGo8rTyWkQG1CZuBScQdLSDGCge0BQi3lAOgk1CLMNCQCNdbzQtAixDYfpBzApBZhx/FL1u4RMonbbJeOY5dINfiGSUgRLGCzTGnwRWPX1D+T9vNRQqquwXeejDtYQooRDGwPEGopB4CqRjLdfTWSTEM6QjHW80KoRoJtPkg5gMlqJJ0HTlu7R8gkbrNdOvefJq3C4bOElKrCEY1dU/9M2s9HCSmoOCWqcFyj4w6WkGKEAtsDhFrKIZ4AXk7qEbe4r0ec+WwIUg6NPmrreSHUI8Y2FURNKOUAVq9HfMxePwiYxG22C9SAjvslUR1enyWkYKzGz2RQhxdjXPkoIQU15+Md24jzybijIYnN5n1C5g6GJ7A6QDyQcgDUbreKydYns0meI80wpBwafdTW8zpyQUy25qwnfyfSGmUUKCeA3Zv2i93RTQes3SNkErfZLi7efVG7AChlrLKsd846sct19KKxfybt56OEVP+Y2WJSequVlDtYQooRBKxm8nki5dD+uEM8x3vTSJ4jzbCEVI0ngGeui4no1BXk70SaD1IO8XN8ZX8XKmQSt9ku9d3XoyR90GcJqb4py8XE68wNY/9M2g9DyB7bBt6bKiZejzpYQorBKILVCaAnUg7tbT3PB18f/3zwjRaS50gzDCmHIT7qCrpeuSfaaNxC8ncizQcph7iNZBza4i3W7hEyiVudAC7aYj3+sqhdAHUJKfelLLMMxmo8Abxy39g/owmgbxJScPT6xviY6+HXLCHFYBTA5gCpnb3hhZQD/H/gnSliZfi4k+RZmg1DyqHZR61/f+eJ2B39eBb5O5HWWEydksRdZKKGTOI228VFBnZRuwDqElLbSJ4jzWCsxpOLO0+N/TNpP+8kpORJz7tT0HzUNSUhdZYlpBgew+YA8UXKIZ4AKtJ8QvIszaakHDbuR/NR6xrRhDgmzXemkL8TaT5IOYC5WMCETOI228XFB7SoXQA+SkipxWyr/mIWY1z5JiHVfjtZzI6ZheajrrGEFCMI2Bwgvkg5wP/rxyb3SJ6l2TCkHJp91L0GHI3LYxPq9wLWN20FvZRDW2MIwwJ79wiYxG22C4SN2D5CK2oXgJKQmuaJhBQcc/5h3PPBUWbhLBjjyjcJqdrlJJxl/EI0H3WNJaQYQcDmAHERRF80QKR/kOQQTyrOXCd5lmEEgSDl0Oyj7jUgOUYGTlO/FzAgcHIphzY3SUwhk7jNdnERRF/ULvEEUEpIjfdEQuphTfTJ0WYJbRjjyjcJqY7TQxPa/JCQspfEFDJ3MDyBzQHii5QD/B9kTkylEzANQ8qh2Ufda4A8jpROoH4v8fNIKYfbtFIOLmSMQiZxm+3iQkajqF0AvklItd98nDzPHBT/TNoPuMsnCalmSSuWkGKMCLzyyitvvvrqq38b2Zjo139l+nONsJrJ50BIt2iASP+wdtywDEPKodlH3WuAQHb8LJfukr8XsIF3/ZByAIuFzP8wztrxuE0St8kbAGvt4khIt6hdYv+UhNRUsmdpNBijQtR+MY5/JhNAzySkIGlM7EhuQ/NR11wImfME8FeAiJD/5rXXXpsLv47+/5cRSa83+blmWJ0AOoiDKBog0j+IU8GIucMyDCmHZh91rwEl8uLdyFPXyN9L/PF/3Q8pBzDbpQxtkbht3gBYaxdHpbSK2iX2T0lI+REjC2M0nnRNX4Xjn0H7+SYhBbJRjTGJXkhIWYx/5wngrwARKb8TkfQ/yd9HBP3Q5OeaYXOA+CLlEE8At5gXUMc0DCmHZh+122nuBjFR//o8+XupSzlMRfPPxPr/NEe0041HVq5vi8Rt8wbAVrvAu44nFp/OJeuHQxQE3vVHQgrGaHzMOc8sKxljXPkmISWzkruSrGSWkGIEj4iQp0b2Dw2/f/DCCy/8ue7PNSOOc6mJzoRtUsqh4/xNK9cvMvBL+qfKi638iuRZmm0wkXJof9KJ5qPuNXqWbRfEufcb8vdSu9OqpByw/DOx/gmLRR++dMeOvzU7JG6bNwC22qXj4m0xAZy4hK4fNvQ76Ivxbn004aF6HmlKlzAas1j+aV+nVUhIAZdRvxcwpUu4+ziej5rWce6mkpCydQ9b3MHwCNEKfUa0Qv+7ht+3vvjii3+m+3PNeG4R37eIY85fvu2weZtS+Pns1fhZflyxnfpRnj979uz5d6+Pe/7dqAnUjxLjxy9F6bWfDpykfpTnv7S2xc/y/aQl1I8S44d5Ilnn5xv3rN0Djy2q84EubwBsvQ941/DOf5i33tYtKgH6YsxjT9qpHyUao2ICCGPWB3w3qiXisvExp1HjhxViIfvzuWvUjxJ980S29vcTFlm9Dw5bMLxFckTzjw2/f2zyc82ATmRrhdQo5UCxImxcAXZ+c0WsyGauIXmWIfaoLuWA6aPuNbq3iQkg1D2lfjcqsHzaCjT/TKx3/kZxPH74nJXr21rF2+YNgK126Tx8VhyfLdhI1g8b+53SpYz6JtXzSOtZJ2oTd287jOafyXWkhBQky1C/m76Zq8VYjbge00et93uvLiFl7R68AzjyERHyX8MqHX790ksvvRphC/w6Iu2Xy/xcEWCAQGeyEaPgi5RDPFjOi2OlvklLSZ5lyHMhSTk0+6h7jc7dJ8QEcPmX5O/GJykHMHgn4ljphJ2+0G5tAmiVNwC22kWFaxD2x8Z+pySkor5J9TyqPy4T/bFzzzdo/plcxycJqb6JYqe2duE2qo9axhJSDCxEpP1pRNJ/H9nnL7/88ivRH/0mIupb0Z//RcHPFcLaAPFJygFWTNcfiknXZ/PInkcalpRDs4+614DdrXjSNX8j+bvxScoBrHv9XjEB3HrIyvVtkrhN3gBYmwBuFTvS8O6p+mFjv1MSUlHfpHoeab3zNqIkbKFNAD2SkIKkoXgyev0Rqo+6FktIwQZIgBJSjF8JrA0Qn6QcwL/7IrZs4IMZZM8jDUvKYZiPus9zUsRH9s0wfx5TU1IOa3ej+Wf0PNsOD3kebAuZxG21C7zreNId9QWqftjY75SEFOHzSAPOiHcjozGL5Z/Z8/gjIaUkm+63o/po/DyBSUgxfkWwNUB8k3Joe9ottuTfnEj2PNKwpByG+ah5jdrFO2ICOMF8R9LU1I6bB1IOcVvtSbIul26zcv2QSdxWu8DuL/WO25AJoEcSUn1JVjqMWSz/TK7jk4QUcHvjjhs1d6gdycAkpBi/ItgaIBCHEU8qJi4hI4RmAhh8K4lJjCaDVM8EpiYVy7aj+6h1DRmT+CfzmERTUzF3u46j+WdiHUeSyfpc88l6VvtRc4AubLVL71z6mLvGfqdiEld8RfY80pQuZTRmsfwzuU7P0u0oMYnGJmPuIo7H9lHX1GQ9iUnEtpC5g+EJbA2QjiTrtveL1WSk0EwAAx/SFpiXpo4V1+1B91HL5HH9aLrjemkq6/bQWTz/DEwd109baeX6IZO4rXZRWben6Y4VG/sd9EWRlbyJ7HmkgXJAvIh9WEPzz+Q63WtFVjJwGuV7AU6POSzieGwfdQ1CajCO6/PakJoDGIHD1gDxgTSbCaD/8/liAnjtIdkzgXWvwyNNFJKDhJ0/jCNN2JEGC4aYNKMFBJp/BqYSdsYvsnL9kEncVrv0j0/KJF6mSyxo7HcdJ+gXs9IGR+HUpsYaVyphB2Exa+TPtQdinEYcj+2jrjVKSFnxOWDuYHgCa5l8nkk5wO9BAib+sJy7RfZMYFhSDmk+6hrIFVBK9kjzSsoB7n+rNZHsmW3n+gGTuLUJ4JhEWuQ2nbRIqoQUYThLbK3imHPgnSmo/plcxxcJqZqsvDG5LvNFzR2hSkgxfkWwNgH0TMoBft87c43YXTp+meyZ4udAknJI81HXQLA0/ujeNatNbGrNgdPUJN72KKlN/N5UK9cPmcRttQvUgY4XI9G7p+qHQyWk6BPa4me6UxcXxvTP5Dq+SEhBvfn4OWatQfdR10KWkGL8SmBrgPgm5QC/71m4WUy8Dp4heyYwLCmHNB91rX/sAjHxunqf9N34JuUQH4+/Pv754Bvjreh5hUziVtpFvu/X7bzvKu2i/PNEQqoWjc14IhqNVVT/DK7ji4RU54EzYidy0WZ0H3WtWdIK20LmDoYnsDVAfJNyiJ9p5Q4xKd15jOyZwLCkHNJ81H6mKcvFM529QfpumsVTqUkcbODdKWJS+rgT/dohk7iVdnmc7Li+O5W0H/ooIVU7c0NMtqKxiuqfyTN5IiHVteOYmABGHI/to66xhBTDe9gaIL5JOcDvuzfuFyuyzQfIngkMS8ohzUft9pq9VrTXsYt070aVT/JHygFs4ONZSUzaE/Rrh0ziNtoF4v7iCeCYWXT9MKXfKQkpwhjZjqMXxTHn7HXo/mlfxxMJqe5NBwS3RxyP7aN2e7GEFMN32BogdSmH62Sk0EwAXV8dFSSxehfZM4FhSTmk+ahrPYu3iB3b/afp2stDKQew/nEyK/Uevs8Bk7iNdoHMX5F1vZCsvdP6nQ8SUp37T4kdpcVb0f3TNk8kpLpX7xSnOxHHo/uoaSBjxBJSDK9hLZNvvL2PZpUB0uhf5z48AjUxLCmHNB91LY1AnbfXVf+kHMD6piaLmTP4i5mQSdxGu8CCUXw0V5C1d1q/q0tIPSB7JswFLNq48kRCqr6APYXvo6bVFzMsIcXwFNYmgJ5JOcDvMY9QtA1RyiHNR11TRyib9qM8l47Vzkoph2Xo/plY7xx74Qwhk7iVCWD0jsWx2Xqy9k7rdyAvIiSkbpI9E2YIC+a48kFCKi2EhZo7WEKK4T1sDRAl5fDYDykH+D1mELX2MyFKOaT5qGsqiHrVDpTn0jEfpRzAepZstZbQFDKJ22gXeMdxP1xiJ3C+Srs0+ueDhBRmEhvmuPJBQiotiY2cO1hCiuE7rAwQy9IZVQbIkAngFTwZBV3DlHJI81HX0mQUXFvngdPeSTmAda/ZJT68Xx5Bv3bIJG6jXWxLZ1Rpl0b/lITUAToJKUwZK8xx5YOElHyGWsMzkHMHS0gxfIeVAeKjlEMb/u6bjmHvQqLpeandt7Vk76Zrx9Fhu5DkJA7PteWgmJRs2Id+7ZBJ3Ea72BbPrdIuQyaAcvdtB52EFOyMY+1CYo4rHySk0nYhfeAOlpBieA0bA0RKOUAcINXASyWA1k7U+Dsdw45DRNPzOjc8/s61+SjlAKbKGq74Cv3aIZO4jXZR5bOid07V3mn9zgcJqXoconkpS8xx5YOElIpDbK3HIfrAHSBnxBJSDG9hY4DYzn6qMkCa/Rsc1YKWgatj2JnIaHpeKcXUXVvPKv+kHOI2O3RWTNoXbEK/dsgkbqNdoKRYfMwZvXOq9k7rd/UM3J1kz1TPRH6I7p+JpWXgOjWZiTxqaCayD9xhUw0jZO5geAIrmXyeSjmAYWrw6Ri2FiHaBFBq8H30Bcpz6VjPouFahD6QeMc3V8QE8IvV6NcOmcStTACjdxzvJkXvnKq90/pdXYNvC9kzYWoRYo4rcgmpDC1CH7iDJaQYXsPKBNBTKQcwzCocOoZ9lIRGcilVOFybj1IOYLXzt8WCZuIS9GuHTOI22gXecbxjcuE2WXun9TsfJKRUNZKn3ej+mVha6IbTtsqoRuIDd7CEFMNr2BggSsrBUg3EKgNk2ASwBa8Or45h1yNG1fN6c+KQOryurW/KMv+kHOAZrj8SH5hP5+JfO2ASt9Eu8I7jBdqNR2TtndbvyCWkkOsRY46rtDq8Li2rHrEP3AFyRiwhxfAWNgaIr1IOYH3TV4kV2cmrNISAKOWQ5aOuDbw/XewwPGgneTf9Y+cPk5PwgcTb7idHTB/MQL92yCRuo12o+2BWv8OWb6Lug5jjilpCCrg8ngDOWGXNR11jCSmG17AxQHyVcgDrnZcEmX99nuSZsAVlUfW8iHdffJVywN59aW4/ag7QhY12gZJilLvQWf2OWkJK7UJ/Ns+KfyaWJuDu0joPnxP3n7/Rmo+6xhJSDK9hY4AoKYfdJ8gGXhYB9CzbLiaAe74heaa+SXhSDlk+aj8bcfxVWkkpH0g8fjYZf4Vc7ipkEkdvFw/iUDP7Xat8tskkz6PiUCP+sOKfybMpCSmcZ6tqndF3Jt6BXPalNR91jSWkGF7DSiafp1IOYN3r9ojJ6bbDJM+EKeWQ5aN2u1FmYIKUA3xg/+iflAMYZgZms3/UHKAL7HbxIRM9r9+BzAiVhBR2JjrmuKKWkIKTpniXLeJ2Wz7qGktIMbyGlQmgp1IOMVlEE780snBl2BMJ1AlgRFJkE3ePpRzA6hP3B6jXDZnE0SeAV+m1KPP6HaWEFPZEAnUCKCfuH9JM3LvXpi/qfeAOlpBieA0bA4T6KDGPAODoVxwXbCd5JkwphywfdQ2OKaiqMEDcoa9SDmD1Kgw3cf0OmMSx26V2lr4aTV6/o5SQwj5KRB1X8uj+LZqj+56l6WE9PnAHfANZQorhLWwMEOpkgjwCgOSPeEU2b4P7Z7KQTICq50WYvKOI0kMpBzDMOqzN/lFzgC6w28WHetR5/Q76JpWEFHYyAfa4opSQ6p27ITWxzwfuYAkphtewMUB8lXIA6zh1TUw0pq9y/0z329DlRFD1vAjle3yWcgBT8j0HcOR7Gv2j5gBdYLdL54HTpHIiRf2OUkIKW04Ee1wpzr/vnvP7pq8U7RJxu00ftYwlpBg+w8YA8VXKAUyKhoIgtPPnuf4QVcohy0ddUwLeS9wLePss5QCmBLx34Ah4N/pHzQG6wG6Xrh2iTGLPKhpB4aJ+pySkor7qvP8t2SruvQ+n3i72uFKnPtfdn/r0tywSO7OX7lr1UctkchtLSDF8BPoAeUIrl1BEAKps0CdznD8PtpRDlo+6RlnCr0tKOSz3T8oBDLuEX6N/1BygC+x2USXFNtGUFCvqdyAzEk/CCOStsEuKYY8ryrjv/k9mi8nnrVarPuoayBqxhBTDS6Bn8nku5QAZfCLbdJrz5+k4gZ8RhjoBPH1dTFCnrXD+bpSUw/q91vwzer6vxO4UFL7HvG7IJI7dLj2rdopd1uhdU7Z1Vr+jlJDqm7pCTADPXLfmn4lRKj8MvJdkZz/qsOqj9vOxhBTDV6BPAKWUw1g/pRziLfk/jHs+OKrF+fN0HsTXhMIkudrle6Ltxi90/m4g7tBXKYe47fafEjuUi7egXjdkEkefAC7aInbY9p8mbeusfqckpNa6l5DqH7dQ7LBduWfNPxOjlJAafKMlVZ/RF+5gCSmGt8AeIErKYYqfUg5gA+9MESvG1k6nz2NDFR5Vz+t2q5gAjpntvK16lm7zVsoBrOPYRTF5n70O9bohkzh2u/TOXit2kY5dIm3rrH6nJKSWupeQGhgzS0wibj+x5p+JqepPriWkHneKE50rTpfGAAAgAElEQVSI0237qGsga8QSUgwvgT1AfJdyABv4OCHTO0+dPk+3hbqQqCT3uEOQ6btTnbeVlHLoOOKflANY7cyNZGGzHPW6IZM4drvAojH+UJ69QdrWWf2OUkJq4N1k0foYZ9GKPa6UhFTEcU7b6c4TwVkRp9v2UddYQorhLbAHSF3KYQvpoMsjgP6xC5LjlPtOnwdbyiHPRy2D4/E3xj8ffH288wzuvmkeSzlEVrt6PwltWIB63ZBJHLtdIGwkXphddTsus9ql2b+6hNRKt88D4zIak3DUadM/E1MSUhHHuXw3cCQej8txw8NWfOEOkDViCSmGl8AeIHUpB9xged0BkuYf7OLEE8AzbncalJTD3pPWfdQ12P0TOw0dKNcra/3jPZZygOe4+zRJbpqJe92ASRy7XSBxLJ4A3nW7M5/VLs3+Qd8UElKL3D7Po2Rn/r2pVv0zMSoJKUiKiSflU4cnrvnCHSBrxBJSDC+BPUB8l3IA652zTuw2Hb3o9HmwpRzyfNQ1iP8TsUatKNerfF9PpRzaWu3IG4VM4tjtAu/WhlyGbrs0+wd9U0hIuY2RtXFf7HGlJKTmuJWQyruvL9zBElIMb4GeySelHHb4KeUQP+NiXFHVsoYt5ZDno66pnbjLd1GuV9Zgd8NnKQewwVETUrMNTduPmgN0gdouUjD3jxPI2zmz30kJqffcSkjZ2HlEnwCezt6Js2nA4WLncat1H3WNJaQY3gJ9AiilHA74KeUA1r0aPxavjCkph8s4Ug55PuoaaADGk9TTeJPUQsuJPfSFxMEGRuOXOAyZxFHb5UFSMuv96eTtnNnvpIQUYixeGes4ncQeTsOLPcQeV7BgpJCQAg7Pij30hTtA1oglpBheAnuA+C7lANa9GT8bt4yp7GMkKYc8H7Xbby7+MXWhqexjf6UcwPr/NEe0383HqO1HzQG6wGyX9huPxATiT+4r9GS1S5p/SkIKKRu3jEFmvKjQg5d9jD2upIQUyNW4bCfg8JjLU7KPfeEOlpBieAvsAVKXcsDVPNIdIGn+de08JlZkK93WHLXx8UDX85J6fIiJKoU+3PZfygGsb8Ji0bcv3kFtP2oO0AXqDtKFpEziBPc1urPaJXUCqCSk8BZxRWZDfxB9XOUs4mwaaKrGpzk7h+sP+sIdIGvEElIML4E9QOpSDriq57oDJM2/zoNnxIps4WZ3z6OkHHAlVtD1vGRFju1fO3s3qgKJx1IOYH0zVond0ZNXUduPmgN0gRpD9o0okwjvmLqd8/oddkWOMqYkVqKxads/bZP85lhCSlUgOTi8Aokv3NHOElIMX4E9QHyXcgDrOHFZTABnrnH3PBakHPJ81LWsmrw2LS+A3BcSB+udvxG93FXIJI7ZLvBO4zEZvWPqds7rdzYSuYpMiSxHY9O2fyamJKQeuZOQUjWITwyvQewLd9QlpL7AvW7A3MHwBNgDZPCtSYIEnnaTDro8AqiduyUmHJOWunsWSxIS6BPA3SfEcdPyL529mxCkHMBslLsKmcRR+52FMomm7ZLmH4WElOx3ndHYtO2fiWVJOdk04PB4R/b8LSc+atkTKSE1CfW6IXMHwxOgDpBo0hd39LdwO7rJAEnzr/3aQzEZ+2yes2dRUg7jcUVksUlO7cQs2OTs3dRFZP2VcgDLCzg3aT9qDtAFaugBUWJWXruk+afE3B1KSKmd58PnrPtnYpAB7FpCCjg8nnRef+jER10bfHMi+sZIyNzB8ASomWD3vhVb3R/ibnWbDJBU/+61ief8YIazZ1FlpBClHHJ91H3OJBYLjlZcvZu8MlI+kbiSnFiNV+4qZBJHnQCuTvRDv6LXD83rdzbKORaZrdhT9ARAJSF1De2aRQYcHk+s7rc58VH7OT8UoVHw7cFsQ2oOYAQO1Ang1QdWgl1NBkiqfwQ7laqQPKKUQ66PmqayMScucfZuQpByiNvQgp5XyCSO2S4+6Yfm9TuKnUpb2efY46ouIXXe2bvJ21nziTtUcuQ1vOTIkLmD4QlQJw+W0t1NBkiWfza25POsLuWAWysTXc9L6rF9OtdZOykph5TYOp9IvOP4JTGJn7UWtf2oOUAXmO3SO2uNmDwcv0zeznn9DuRGXMcqwliMJw/R2LTtn4lBHeB4Eh9xnZN3U7CQ94k7VP15RHm0kLmD4QlQjw+PXswM5qewPAJQRweIW/J51rXtcCLlsMeZj1pGUJFBSTmkZNf6ROIqeWgyXvJQyCSO2S55wfwUli0h5T5GVlWgeViz7p+JKQmpiOuctFFByJFP3KGSh47hJQ+FzB0MT4CaQKDqMuLucpkMkCz/8oKHbZgtcrSi5wXlrka5K3cVgpRD/CzX8ZOHQiZxzHapj0e8XS7Tdknzz7mEVFwmsQVdX8/GuLK1yM30oSCZzyfusJE8FDJ3MDwB5gCxIVhqOkCy/HO946COR5ArbNjR83Jb7griDUVb3Hbin7bdb0dPHgqZxDHbBXac4z6HWGfZtF3S/AO+cCohpSpsTHXin4nZCnPJsiI5L5+4Q20AICYPhcwdDE+Amsm3bo/TI4AyAyTLP1jBi10nNzFHcCxuQz/MipzDJ4me1203el4qxill98cnEo93YyDm6I8TUNuPmgN0gdku8E5h59llFYmidknzz8YucO5zKP1Q3BrJNsZVnp6nDYN40bzdWJ+4w4bAfsjcwfAEqJl8y7a7DQIuMUAyJ4A5JYRsmAoCPnPDmY+61t+SZB1ecqPnFYqUA9jg25PFs7Z2obUfNQfoAq1dWjvFLtc7buvIFrVLqn+OJaQg8zfe5UKukWxjXAG3uUwCLCrp6RN3qN3RZXgC+yFzB8MToGbyzd3gXAagaIBk+dezcofYrdx5zMmz1Gsk33fmo67Z0B3Ls3j3JwApB7CBj2eJdryDU+owZBLHapf2O0/EpCp6t9TtW9jvZObpmxOdPAeMwXhShVwj2coE0FLN2yzr2nFMTKoiLnflo64pGbB5eDJgIXMHwxOgZvIpIVB3dTKLBkiWf90b94st+U0HnDyLFAKFzDVXPupaXlYuurXKMkmTnflnYv3jZLWDe2jtR80BusBqF6gcIarkLCRv3zL9Dkp6xbvAT3B2gfPMVmUeG+PKdSGA7k2Sw/c781HXQBwbuxBAyNzB8ASomXzy43gF5+OIMUCy/CtaPWKbLd1BK3peObp86G1UsPvjE4mDYVc7CJnEsdrFVpUc03bJ8m/go5mou8B5pnQHkXnKyrhyLLBfdIrjE3fAghF7kRMydzA8AWomH/LxGMYAyfJPxY+40POSxcAtEKMVPS+5O7oZr+Ztlqndn3HpxOgTiYPJMAc40sFqP2oO0AVWu9g4HsNolyz/sHeB86x78wExFjem73LZ8M/EgONc7Y4WxXH7xB02whxC5g6GJ0DN5JMB8g4Gf9kBkuWfy5q37XefisH/0UynPupa146jYtdh1U7r76Zo98cnEgeDIG7MRKeQSRxtArj7hOhvy/EC5DHaJcs/lzVve1Ylu1w7cGOVbY2rgY+SUJe79jcBVKzyN8P1Q236qGVJqAtmolPI3MHwBGgDREpkOAqOLjtAsvyzlV2XZrUr9oKjreh5HRC7oz2L0rPrMK3z8Llk92ejM/9MDGQc4g/y1kNo7UfNAbrAahcbEhkY7ZLlH+xUYu4C51nPws3JLtcZZ/6ZGHBcvDuKnOyWeq+W/BrJvnEHttRRyNzB8ARoA8SCSC7GAMnyr66vNdv6c0BSTDzZnLrCqY/az3viirNqBxBnmLf74xuJY4udh0ziWO3SvWYXukguRrtk+Qd9NX7e3SesP4eqkpOxy2XDPxMDjouf94z9RMD+MYle6a10vVLfuEPJXSGJnYfMHQxPgDVAlEDq5/PJB1opAngkFfbta4+BLE48oZqLL5BqRc7hwm0xYZ24xPq76d5yUEyoNuxz5p+J1csdbkVrP2oO0AVWu9gok4XRLln+qV3gLfZjZFWVnAvDq+TY8s/ElOD9kQvW3w0cp4qKRR1OfdQ17HKHIXMHwxNgDZDauZti0jB5GflAK0UAssamg+oD9RJJ2936qHvNG4/EZP7TudbbqHv1TvEx/eqoM/9MDCq5iGoH69Daj5oDdIHVLr2z14lJwzHcKjmm7ZLlH+xUxouW1busP0f/n+aIScPNx878MzEoA+ekGECJmuW+cUff5KT86Dmc8qMhcwfDE2ANkI5jl8SHcfZa8oFWlgAGRrupP6pinNbhF0m3QnIPa2J3dPQ0620EcYbxB+PAaXf+GVjtLG61g5BJHKtd+qYsEx/GszfJ27dMv+vcfzqJkd1i/TkG3psmOOpR+i6XDf9MzFk50AdJyNH70537qGu9s9aKhc7xS2htSM0BjMCBlsm3PzkaW4xzNIY1QPL8y6tBi2mqEPj2r537qGWwun59fLxDant3VNVkPp5ek9k3Em+/+iBJ6MEJdQiZxLHaBcJG4nF47QF5+5bpd/ABjxe7syzHyManFOPjsYg9Dm2NK5j4YcbIZj6/DDnKOaXwjTt6Fm8Ri9396YtdnTak5gBG4EDL5JPHImvsH4tUGSB5/vVNSrbkz+NsyWcOfIsxTtbkHN6bmhtfg2Uqxul8eoyTbySOXe0gZBLHahdZJQfq7FK3b5l+B3wR7wJH/GH1OWSc8nv4O/G2xlXn3pNJjOw2q+8GjlGL2sA37oCQgbxwF502pOYARuBAy+TbsM9ZYHSVAZLnH6zgMbfks0zFOB3Fj3GyJufwyZzcDDu0+8gYpxvpu7C+kTh2tYOQSRyrXWxVyTFtlyz/XMXIQtxffJ9ojLj0z8SwY2Qz7yNDjmZlhxz5xh1FCW86bUjNAYzAgZbJ51AaocoAyfMPYnjElrzd7MN6jNMN5z5qP/OEfI0tLIM4w/jj/7Dm1D8Tw6x2EDKJo7SLrJLztpvyYVXaJdM/GX82Ojv+DMNsapXaGle1M7gxslmmsvEXb3Huo64pyasVX6G1ITUHMAIHWibf/I1iMnX4HPlAK0sAakvesv6YzRgna3IOlvTHhliJGCffSBwMs9pByCSO0S42q+SYtkumf45iZG1WK7I1rlSMrGU5sDIhR75xhxK9n58ueq/ThtQcwAgcaJl805OyPKfsl0eqMkDy/OuSW/KWKxAoAVALMU7WJoCyzuah9DqbKKZinKY698/EMKsdhEziGO2iquRk1IKmskIFgXenWsnObTSocRtPGBbiV+SxNgFEjpHNsjIVeXzjDlX2csYqtDak5gBG4EDL5GtZJD6Kl++SD7SyBNAla5Aus1uDFGKcBi3FOFnT81qZ1CDdedxe+8gYp0+yY5x8I3EwWe0Ajrsw2o+aA3SB0S5QMcJWlRzTdsnzDyoI2dDna7SunccEP0Vj0bV/2iZjZC2XBO1Ztl0sUHNCjnzjjtqlu4LvWnCO9EPmDoYnQJsAyrI8t5+QD7SyBAC1PEWFjg32nkPFOE0m8VHXujftF7ujmw5Yezeq4khOjJNvJA6GWe0gZBJHmQBG79BWlRzTdsnzz0WMrM0xaHNcQTwnVoxslkF/iSeAOfWYfeOO9tu45UdD5g6GJ8AaIFBSTciGdJIPtLIE0HE62ZKfZm/3of2O3Rgna3peO5Ldh1X4uw/q/Z8ojnHyjcTBVLWDvSdR2o+aA3SB0S42q+SYtkuefy5iZOu78Mec+2diwHVYMbJZpmoOn86uOewdd0Tfxvhb8O5UtDak5gBG4EAZIKoszwT6QVaBAGpX7lmPP6pdtnsPa3peFuOP1D0OnBEf/5x7eEfibSDsjVftIGQSx2gXJRxsoUqOabvkTgAXJhVsDp6x9gw243Btjivgunh3NOJXW+9GxeFeyY7D9ZE7oHQdlrB3yNzB8AQoA6REWR4KKyIA27tzYLZ3Ga3peVnMQJTWteNo4S6jjySOOWkJmcQx2gVzMo1phRJScnduB/7unDSbu4w2x1WZ3TlTK5OJ7yN3qPKjGbJXVduQmgMYgQNjgLgSRtUZILn+OdAgsx1naE3PS8bnTVxi7d10b0xinDZnxzj5SOKYx5YhkzhGu2Aep2NaoYTUpgOi70Z92NYz2IwztDmuZHxex5Hs+DxTK6PF6SN3qPKjGcL3VduQmgMYgQNjgEAZLyelkTQGSJF/tqsQdFrONLYm52CxCoE0EESNd1F2ZWca+0jimIkLIZM4RrtgJtSg9v8iBYGduKK+aWazGo/NcaUydKOFkpV3U7Iaj4/coUpfXkgvfVm1Dak5gBE4UDL5TlwWH8SZloujawyQIv9kHVLQr7LxDKBTZVNr0BrJWaxDKk2Jh+fEOPlI4pjSJSGTOEa7YErqYFqhgsChJEZ2wSZrz6DqcVvQGrQ5riA0okijz+jZpXh4gdagj9wB38h4wXPC/Fg/ZO5geAKUTD4ZzL/IXsKA7gAp8q9/bFKlA0HUN81AqT4mw+1fk/moZaraAU7Acpop8fCTV937Z2CY4sUhkzhGu2CKamNaoYJA1GcxRX2HmeXxZ3NcAdfFi961u628G+gr8fiL+g6Vj7rWg5g8FDJ3MDwBSiafCubfST7AqhIA1Ky0uQPRs3irGPD77NQbtirn8N40q9UO+scn4uGXssXDfSRxzPJlIZM4Rru4kAzRbZc8/+qivovsPMPDmuhjo+3swNscV6pO75KtVp697A68j9wBCW9YyUMhcwejJF555ZU3X3311b+NbEz067/K+9nXXnvtP0T/+zcvvPDCn7/88suvlLk+SiafCuY/SD7AqhKA7Rik3tlrxfWPXSTzUdcg/s9mtYOBMbMS8fDsGCcfSRxT3NsmiYfAHUo02FIMrkm75PkHcXnxBHAMjqjvsOtbjsG1Oa46jl4Ux+Oz11l5dkguia8/Jz8G10fugIQ3Ie5tnjzEE8ARjoi0/yYi5rnw6+j/fxkR+fq8n4/+/mz0c7XINr744ou/LXMPlEw+KYmQE8xPYWUIQGUhWgpY7pu8VOxynbtJ5qP2syMGLKfZwDuJeHhrtni4jyQOhlXezxaJB8EdJYP5Kayw30lR36gP27i/7Sx8m+OqdvamePbJy6w8e9ksfB+5QyUPIZT34wngCEdExu9ERP5P8vcRST8s+Pn/XvUeKJl8FgVLTQdIkX8qYNmSDln/Z/PELte1h2Q+arerzWoHUjz8j/ni4T6SOJhMHmq712bcfjrcUIQQuAMSr8oE81NYKQWBURPiPmwjRk9VybGUWGdzXLVfeyB2Lz+fb+XZVWJdgQ6nj9yhkocQBPZ5AjjCEZH21Mj+oeH3D+CIJuvnIxL//OWXX/6v0f/f/t3vfvfvy9wDBkitJjqTrvV9IYL5O09eNboOtoFfRf51JwHLPWt3W3mGgQ9miAnggzYyH3VNVTuISAv92aV4ePR+qPwzMfi4xbuj1x8Ytx8GVzQjBO6oyYnC2Pnk7anT70D4Ph7bD9vR7991UCTW9S7aTOaftt1vKzW2da1nrUis6/7yazofNa3zpJjY90WLa4w2xOAKhqeIyHhGtIr/u4bft7744ot/lvNPfgP/+e1vf/tvI8I/VuYezxHw/dRlcaf+5dG3GJdzip9PXoqf/cc1O6xc/zvQGfzD2OfPfnlm5fo28ePmffG7+enIGfRr/9ImjtC+H78Q/dou8EOy6Pnl3mPjaxnSRCpC4I5f7oo4tx9mrjJ+hxT4fpzIYP6lvRP92j99LSaAP27Zj35t23j2yy8x5wH32cCPq0XIEXB3aPjlkUgg+37qcpTrGdIEgxoRMf/vQLiRHW2y9bAaj0j8Hxt+9nHWdaLV+3+L/n5C8tt/Hf37gTL3h05kukIaSARLa7dbyVdYVVeAncfqAcvoz/BETHIG35lM6qOuNQYsY1+741w9TojKPxOD/hLvjh6/aNx+v1buUGNvjoWxZ2hl+p2M7+04fxP9/jDmZJUcKv9MDBKk4t3RJ13o1+5LEuuKxp6P3FG7VU/uwWhDXe5gBICIlP8aVvLw65deeini5Ve3yL+LyP3lxp+NSPw/Rz/zH+HXv//97/9d9LO7ytwDBgh0JpNYBJuCpaYxEkX+2QxYbr/9RByFfDyL1Edd69p5DC1gudk6jpXLFLTpn4mBxAWGvA/4hckZEiFwh225ENN2KfKvnuF/Cb9/ySo5O+0k1tkeV0re584T9GuXTazzkjsQBfZtcQfDI0Rk/WlE5H+fxOhIeYbfRCR9K/q7v2j62X+CVX/0dx87y+RzIBhsMkCK/FMBy5/NQ79/7XKiFTbeXDDYxEdds1ntoOzH30sSb2sQ+P7yiHH7oZNGnQ+85g7bgsGm7VLkn02NT9uJdbbHFYikx5O0y/fwr10ysc5L7kD8XvIEkGEM4wHioGSYyQAp9K8hYBn7/h2nrondxWkraX3Uff5vkkzEL1ajX7vsx99LEm/DK/EXMombtgu8O5slw0zbpcg/m1V+oMJIUZUc2/4ZPf80UeKv4/Q19GvL5Ju2++2kPmo/P9KJWcjcwfAEpgPEtmCp6QAp9A9WZBCnVyBHomOdh8+JCdS8jbQ+alrt4h0xgZ2wGP3aZeV3fCXxzt0nxA7m8i+N24+aA3Rh2i49y760qsFp2i5F/tms893fsriwSo5t/0ysd94G0bZfn0e/dln5HV+5oz+JmQcxcdM2pOYARuAwHSA2JwmmVpYAZMByniCxjnUhTRIwfNS6tqx28An+5B5EXMt8/H0lcfiwYUzuQyZx03axOUkw7vsl+p0SJF6WL0isY/2fzEaZJJj4Z2Jqch9xIOq1Kwhw+8od8K2MJ/fRt9O0Dak5gBE4TAeIzWNCUytLAJCkUVSSTMe6thy0tkNQ1UctU8f7U9GvXbYEn68kDkdb8cJnutnxfsgkbtouEBohjgmvk7enTr9TJcnm5pck07GBd5Njwsd2Eutsjytbx/tyUQplJKl91DUlsG94vB8ydzA8gXEm30E8ZXNsK0sA/eMXWTlu6V6NkyiA4aOWwfH4Gy1x0DJ2gg8Uco/f+ZkbdP4ZGAS3YyT4hEzipu2iEgWu4CcKmFqpCeCZ62IREPVl1PvLRIFRLaT+mRhwXrz4XbML9brA0fG4a1lE7qOuYSX4hMwdDE9gnMm346g1qRBTK0sAfdPtBFz3LN4iBvp+/CzBqj7q2sDoaWIn4mEN9br9Y4WIbvvV+6T+ab/3O0LQFeQuTNuPmgN0YdoudamQp+TtqdPvalHfFZVMFuDePxprcd8aPZ3UPxNTWf6LcSV+gKPjSfeMVeQ+6hp8K+ONgR3HjNuQmgMYgcM4k2/DvkSw9CD5wNIlgN75G61ILvTOWmNNJ6yqj7oGyT3xR/rGI9Trylq6UA+W0j9te9IlRL7fmmTcftQcoAvTdoF3Fy8uondJ3p4a/a79rlwE4NYyhrEWTyw/nUvqn4kpnc9Za1Gvq6Sp5hfH3vrKHUpgf+N+4zak5gBG4EDL5MMO9kWwsgSgRFd34Yqu9k2SgqW3yH3U9mHiEuHDhduo1x2EEnnw8X/aTeqfkQ9vm09gQiZxo3ZpTSbQb08mb0ftfhf1XYxFQLPVzt8Wu1wRf5D6Z+KDqvSD6wMIY8c7ixFnU/uo7QMrCDB8gXEmX8lgfgorSwCwEpNllzDvrwRLr+cLlrrwUbt9Zya7mCeu4F1X7p69Xfzh9JXEwerJQ/rVDkImcZN2gYSrssH8FFZaQcDCLmbHictilysae9T+aV//2kMrAvvdm8rvnvnKHVjJQyFzB8MTGGfyTVkmdojO5gfzU1hZAuj6KoljXIUbx1hWsNSFj7rWs2iz2OE9cAbvme+Wj5/zlcTBlFabgZxDyCRu0i4+y0dV6Xdw/BsvAu7ixTF2Hjgt+GiRvcQ66+Mq4rx4jL+PG8dYj587Su+jpkHiW9z3pyw3bkNqDmAEDuNMPge7XCYDpIx/MLlBz2SOM2jHW8mg1fFR12xkMkPWZ7w7MK44g9ZXEgdTcg4Gu6Mhk7hJu7jY5TKx0goCSTJT7Up+MlMVs5VBq+OftgH//WFcrCKAyX8qg/Zg8YLUV+7A2h0NmTsYnsA4k290ssv1wN4ul8kAKeMffMDRtQxlJp/lEnnW5RxktYN1e9CuCbpvokResXyGryQOVt8dPW3UftQcoAuTduncL3e5tpC3o0m/k3JGIAmDde+yVXJc+GdiquQZooKAWnR9U7zo8pY7HuDsjobMHQxPYDRApF6V5V0ukwFSxj9IcMA+joIdURsxMLo+6lrn3pPiQ71kG941ZRWNuRvI/TMxVQvWYHc0ZBI3aRdVC9riLpeJlVYQmCtjoPGqmfQs2SoWFtHYo/bPxCCLWZwO4SkIqCoaJZLSvOUO+d18w+y7GTJ3MDyB0QCRKxmLelUmVpYAVD1jxJJn9TiPZV74qGsgYYMt56Dq6C4rzoLzlsQjgx0a093RkEncpF2619rf5TKx0goCy8qVNKxiSj7qeLjyUWB9k/Hjw1WJvIizffBR1zD0VUPmDoYnMMrks5TphWWlCUCWPHt3Ktq9VabXHPwyUVo+apqSpJi4BO2aVUrk+Uzi9d1RfbHbkEncpF3ULtc+eyLpJlZaQcBCyTNb0ks6/pmYDYWIgXeniInTo+ISeT5zB0bsfMjcwfAERpl8SNlMtqw0AcCW/KgJcdAy1lE2ltYTmo+6109qb8LKG+uaPat2Bp/JB4axOxoyiZu0i4tdLqN+X1FBoHv1TrR7949Jdrlu4dYm1/HPxNA1Yp92i8SSP07wxkddw1DPCJk7GJ7AKJPP0S6XyQAp61/ZyhRlrYpelSsftay1U+yOvjMF7ZpVamH6TOK187eMd0dDJnGTdlG7XOft7XKZWGkFAVmZIurTWPcGcex4l6vVXoUUF+OqXiUKR18VuDnmog/LVV7xmTswdkdD5g6GJzDK5KsQy0VhVQgAuzC9qi6yE7e6iImPugZVOwZLVO0oa33TVgryO33NC/+0372MHf2TfuxoyCRu0i4Qb1s2loukbcsqCJy6JhYB01fi3MOnFnEAACAASURBVFtWF4nGnA/+mVjXzmPi+4BUJ752ubx8lCsfdQ0jdjRk7mB4AqNA7s1JLFe00qMeUKYE0Dd9lZiUnLyKcu/eeUl94cPnvPFR10CwGVPsVmqntV8t1k7zmcTbHsvYUf3d0ZBJ3KRdYEc53uV63Enfjgb9rhb14XhSEvVplPveKS+S7sI/EwPui3dHS9TtLWPAzfFke8aq/7+9Kw22sjjTManKj9RMZlJl/pDMVILgTNX8mD1VmUpmUvNv/kxNZSap5M/8yGRS46QMlwijRjREEO4VDMiiAqIIGllcAaMQF1zYgghGREFl56Jwd7iXLEam3/6+7vNx7lm63+7zdfc5z1P1KHc9573d/Xzdb79LNDZyqb2jG190GsPQGgAkDqdAbl2VfWfwBeUqAFQE2rTAqAl1fbC9/uqDudrI5YV5uXf0zaNeft/oj5cad0iJWcSJFI/kEjuasoizx4ViucjLZRjLFYLG8+742WzDJua0j9ftO3A021DOWxWHfQ4kD7/csC1qXu/ThKpg/7Bhwf6YtYPin127T6WsHUAkcArkXvm4cSxXCNoIgO+OFxe6V+ZerhPR2Mglnbi9eUdlh5T5xrUjYxZxomvsaMoizh0X21iuELRKIKOabtP9dLygAsc2Xq6W2+fyGto7utLL77PtkBKzdviIHU1ZO4BI4BTIrWK5Xm0eyxWCNgLgo6ZbkWX0Aba1kcvh+z32A1YdUgxrR8Ys4kTXVmApizh3XHQrQE/Xpq2gVQKZh5puimX0Aba1j03P3lHb2pExa4e+znaIHU1ZO4BI4BTI7TlxwjdtBIDqkbnWdNMsqQ+wrY1c+vSO6tqR3WZegZhFnEjt7EwTWurZF1oDuOCOi06cWOwpcaIFtEog89gPvYw+wLb2sak7Xvjxjg4/YFc7MmbtsE1oqWdfaA0AEodTILfn0im+aSMA/bs8NqfXXq7W9gG2tZFLn/2Ade1Iw7igmEWcqMMgmMk+KYs4d1z09Zen5IBW0CqB7M6HsoPwa+4dL8rqkFLWuqJe6L68o6TN8rC1+82obGT9/Y+qZB9+GETK2gFEApcFIgPgPZYH8b7ILASg740j2cbEQz/gsvoA29rIpY+OF/p3qT7A95o9/GMWcaJOhNrCS4RKWcS540JJYz7Lg7SCVglk9z6WHQJece8HXFaHlLLWlc9+wBfm532AhVbHZCOLKhHKodxPytoBRAL2Ajntv0Cwb9oIwLn3zmT23HqP8+uW2SGllGw+j/2AqS6izcM/ahE/OyKL3LoU/E5ZxLnjUikQzC+B0WrazDtd83Ore83PsjqklLWufHS8UCRtlpvJI2eispFtjyqF1MsrhZSydgCRgJ3Jp4rgemwR5ptWAnBmMCvAesMC59fVHVJWtL5DShki57MfMG2UbB7+sYs4PfRdWv6lLOLccVEtwgZ9tQhrAa0qCDgeAoqkGwi5YWphH2Bb+1zosx8wabPcMJ0x65ASu3a4tvxLWTuASMDO5Nuft8FasCb4QvIlAL5aMJXVB5hjI+s1PPYD1v1BDSvgxy7i9GBzaYeYsohzx2Vk+SPZpmDHG8HHz8e8G/C43svoA2xrnwvpbyLXu+tmP29JSRodm41c0rMza4f4LnsMQ2sAkDjYmXyOD74yaCsAvsS3rD7AHBtZZIhvPWqPgOHDP3YR1/2AmQehlEWcOy6x9wG2nXc+tbCMPsC29rmw4vF36wfMOYTGrh2u3tGUtQOIBOxAbnX19bOngy8kXwKgH0yO1y8+Y4J828glBStf9JDwc35hfurdb3bqjV3E9YNpFs87mrKIc8dldFYey/Vea71cTuNqk0C2/53sELDwQbfX9RiG4tM+F9rG/Nb9GzPCUGLXDuUd5T4nUtYOIBIgkLtCSnKQJ7KdbgHYug+wh6xA3zZyqfsBH3HrB3zhtuXZ73nndFT2sen40E5ZxLnjYhvLFYJWCWSHT2WHgDkr3F6zpD7Atva5UPcDNsz6r8f+nW9kv2eZeSJa7NrRyQlkQCRgB3Kv2WwVyxWCtgIwvDq36bk9Tq/rsy6Ybxu5vDB/lVUJhnocvSnPfDvdH5V9TjapbL7T9tl8KYs4a1zEuMdePcB63p3KbbppkdNrqlJUVO4kKvtcbPJUEYGeM9KTKJ47sdnobtNT7DEMrQFA4mAHcpdUrsCFtgIw9OhzmUt+00tOr6u9XIfda1/5tpFLPd4u3lFV++r/7ojOvlDjnbKIc8bFl7es1bROIKOaqD+83SlEQnu5PJRb8m0f+3U8jffgxhczb5nQ6Nhs5I+3W3mtlLUDiATcBWJblDMEbQVg8Okdmcis2+L0upVAbl59p1bayCWdUl09vpzq97GLONGl1lnKIs4ZlzJrZLrQdt756Iqks4kf5HmEWmkfm71+6sUOr92SHc6f2RGfjUy6Nh9IWTuASMAO5FYxYUfdYsJaSVsB0C2q7nuC/7q9g94yZlthI5c6m+8JfmZz35tHM2/APPP+l7GLONGlE0TKIs4ZF18xYa2mdQUB1RddzHHua/pYY62yz4VjN7rHfJImyzUmNDpGG1lj4BjzmbJ2AJGAtUCoybeHK4+WLzBLAejfeyg7kRn2qa35mqpA9m3Lo7SRSx/eCerhKR/+d62Lzj4X6nZwz9i3g0tZxDnjQh4cOY/WxtsGjjPvaE7LEIndB/nzyIOXvVX2ufDCbLvEr1okTZZ/X6HRMdrIIoXEiGeoTUhMtX2hNQBIHKwFcrIvO7nMWBx+EXkUAOpX6RqvQteAXkpCtMhGLqlun2t8kg56Xt0+gdxEihm1jU8q2hdaA7jgjMvQI896ibNtNe0TyDY5J5BV4mxbXyC7zHWlSz/te4f9O3RPYYs42xS0Y3TGosw7esosKa7avtAaACQOViD32yeyjVL3yuALyKsAeOhvXLnieixOG5mk2ogu8SpETtmDFER84PlX843tJtb4hdYALjjjMvxAvlESf7PQ4+Zz3vkoi1VmXHWZ62pkBT9EQpETV52CdlyYe2+2sX37JGsMQ2sAkDg4C6R/79vZZmAx/6q0DHIEwLUSv0okKeuKq7RsPg81ynQbOIu2UCmIOF372V5tF+0LrQFccMZFX5X+kn9VWgatE8g8tIOj5Kiy4qrLXFeVEAnzBI7LyOxElIJ2cK62i/aF1gAgcbACuV/0kCxRAjkCYFuouJpDG/Irrs0vR2sjiypeZfodMgaU8zs4hbZTEHFOckvRvtAawAVnXCrJEseCj5vPeccpVHwZKa56+vwsrpq5vlppnwt1iMQjz/LeqyolYxlXnYJ2cJJbivaF1gAgcbACuX++PVvQ67cGX0C+BcC1iPPwqiezBf3C3mht5HL05sWZd/TEOdbP62LSB8wzJVMQ8bPHzmbe0R8vZY1faA3ggjMu9DeSc+j42fDj5nHeORdxFmtKzqGbl0RpnwsHXshDJFZtZP08t3RQCtoxtG5r5jAQz1TOGIbWACBxsAK5N/wim7RPvRJ8AfkWgJGVj7NPZMTzSx7OvFx73orWRi4v9KzMNnBvHWf9PKdWWgoiLr031827NDZtnrX3JmURtx4X9Xe6zv7vVDatE8jEnJYbuJnmNS6L7Dt4PNtA9twXpX0uJC2UG7gla1k/zy3PlYJ20E2RdKaIZypnDENrAJA4WIHc9+derm2vBV9AvgWAvJrcExmREmPkJoe5SSrDRi5JwNmbW+bDPwURJ47esiT3bNl5R1MWcetxOc73lJZN63nncAggUkyk3CQt5W2SWm6fA+nAmG1ueUmD5Gjg3DiloB0D2/bm3tEnWWMYWgOAxMFZINrL9erbwReQbwFwvd7W16Qn+6K1kUu6wsmut+0zOLWHxPLhn4KIE8lzI72jB+02/imLuO249B08lm0EbrePlSybnHmnr7eP2V9v60zyBzZGax+bjtfb3GvSFLTDxTuasnYAkYAVyN1TrpeLS44A6OuGlYxOBR4SJcqwkUud4MKo4UZxf1mixKpo7XMheW443tGURdx2XMr2crmQlUA2737rGFdF10SJMuxjs5jgwmgcoMNyXt4fr41MVryj9lf/KWsHEAlYgdyOyQBlkSMALr1KfZRKKcNGLl1K3PTvUo3P10drnwu1d9Syvl3KIm59uCrZy+VCVvzw3Xkh511v2s8f11IpJdjnQpcSN9xe20loh/aO2jdVSFk7gEhgvUDODF4ao5pM1/+07QK55c84tHLzUSy5DBu5dClyrbuAWLaSS0LEBakLCKcQcMoibh1fqwqBP/Z88PFqxbxzaeXmo1hyq+1zoUuRa24ruSS0Q7VVnWrfKzll7QAigfUGiVmTKQRZAtA7mBcdXWD9erpdGrcWWFk2MunS5q7S6H5btPa5UG9w19hvcENrABf2G6TN7A1S2WQlkD2h5rh5pxtFH+3SWm2fCys1QO3b3I3dsCC7cWJskFLQDpcNbmgNABKHdRzPq3kXkEVxdwFxEQBqBScF57Rdf0bdDeBBfjeAsmxkvZbyjs623/xzH/6piLjqBmIb35ayiNuOi46TjLwLCHfecQ8BxAuzlzkVoC/DPheS59+2C5Dkqf7sipTRnjMV7ah0A7FLqkxZO4BIwI7jYRb1LJNcAdCNxw/Z9WfkXgOGsJFFh+t/HR+12y4+KhURP6eCuS37Y6cs4tZJEqrv6Vsngo9XK+Ydxf7JG4C77eJc5TWgWFOca8Ay7XMh9/qfeuTKdSXmTuw2cllpHtA58cNAJEAcz3hyT2Qjuj5iOV1AXGzkkko5cOrdcVuApSLi5C3meCpSFnHbcdF9ti096yHISiDjtgRU9RFvKacLCNc+F1JnJOk4uN+u3p2+cWL0nU9FOzoxfhiIBIjjGc8RZqFrio1zaSNXpo1c6nZulsHcLoWSUxBxImeDk7KIW40Lc4Mciqx5xyx0rZLH2G3kyrLPgZXqCnbxw7pQsuXGMYSNXHZi/DAQCRDHM5661Z1lvTsq/yKvuN7rjd5GLkeWP2qfrUj1EalLwvT5rFZpKYg4kXPFmbKI24wL94o8FFnzTtW7o243FvXuaC3Jq2OxtqK2z+X13u3NNse33mP1c7o+4gb7+oipaIeKHx65a521faE1AEgciOOpITpbd9knc5D4Tyu/z2npsTzrtlhX5a8kjyyL3j4X6sPRbvPDUcoibjMuFPvJeciFIjt+eFaezPGu+SFQtzpbx+s+VKZ9bKpD4DS7Q6BKHhm0TR4JYSN3LDowfhiIAGPX9nz+o8ERxPFUkZPRee7ImdKLQLvYyKUuBv2weTHoTojjIXLCI869P3hptOu2vxHL8YrQemCBK+g9f/Thh8bjMqAy5BkZsiHoHD9s0Saz7CLQLva5UBeDPmJeDFr3H2fcOCWjHczwiL73ei+N/c/sz4UWAyBRXOzqPnpx5tJL584ansg6IY6Hfu5Qnnk2Z4X5YtQ18tYkYSOXnFqHOsZl9ebo7XMhJ0Fq6KmXs7qTU+b+e2g9MMVYV89/0Hv+3bY9xuMSIkPehdx5N7x6U3YIeG6P8c/oGnk77GvklW2fC88vsK91SPVms4oMp5KwkUvr0mMfDGdx1eIZHloPgEQxNrXnmFyQhu15OiKOh8god0IJI3JjdN8TadjIpO7pe7t5pqN++G+0f/inJOKcEknUVSXVDeBvHtxkPC7cUhehyI4fFhtcOdfFnDf9GeoDm2XI2/cQLts+F+qevi8aJtepLhnUQ5hRHicl7aBnqk1olbpxwgYQYENMnufkydOwxyI3WDUUXQSAMvnkgjz2gdH3D27Mhb+kZu4+bGTxZF/mBZ6xyPhnaFOcCf+++O1zIKdIusqqvtB121+F1gNTjF4796/pPf/6zgeNx4VbWikUufOONje2B8HRmxZl3h+xtmK3z4WkjTbJdaS9nKzqkDZyaZtc2f/aoWwDOLXn2dB6ACSKi109K+SCNDyVd0ocj1yQP12dncpff9fo+3UfUEawcigbuaQ2efKB1Ttg97fcb/a3DG0feyxUm0SLTim0kZbCf+3MT4fWA1MMfK/7j+TD55YlxuOiO10ctr/KCzKWzHnXt/+d7BCwwDAU5PRA5gG+cWES9rmw0inJ7PlBeiH/lkI/UrGRS9v4YQoxyDaA3ctD6wGQKMTkuSGLWTK7ruiUOB5i5brCzGsVqjxOCJGzzQS39aaGto9N29CBvM2V+JlzobXAFmNd3X1yTE1ilhwa3ociO35Yea1m3mX2/YHCakKsK9vkOo43NbSNXNrGD6tn8diUudeH1gIgUYxN7f5mtsAeN5p0nRLHIxeYuq4wjFvTm6K3yy2PEySY26bcCW2Kfni73ABwyuOkJOLE0ZsXGxe8VvGUYh3uDq0FthAbwF/KOWAStyb+FnJTdHN5nS5cyZ53lnFrocrjhFhXdGCUm13Dtm5DG+3jKUPbyCU9U7P4YbOC18pBITaA3witBUCiGJ06++/kgrzDrAI9J4srJF0EoFKd3SxzdewGu2vRGGzk0qY2F2XvyTl2m/m1aGj7XHherCXT0AFVAFhsAB8OrQW2GOvqWSsPg9ubFwTXV3mGOhMDXeadzlw1uO5m1RwNbB+bveq6e4HR91PVANuySsFtZFJXkTAMHaCuMfJQ9YO5fxtaC4BEMXTN3M9kJ/PFRpNudIa5dyMGughA/5638tp1Dzf//hO5h2OG2d8xFhu51NX5DRJe6ErctqZiaPtcqNsIPt/cSz64OSsBM9o1d3ZoLbDF6JTu2+QceOrlpnbq7GhGO69QdIoftqhdRx0ubBIjYrDPhSrm1SThheqG2tZUjMFGFlUbQctn8WDXzD8OrQVAwrj4I8PCzir786Y0agC6CoBNQD/1xZXfa9sEPrCNXFJcpLy2Wtk8dMA28DsG+1yoy4AYbI5V4pDYAH4ntA7YYnRKz3+ZjqsKp+CUAQpFl3lnkxA2cm8ea/ySfYZ8KPtcSOWjpIf8QPPQAZ049M7ppGzkUtcCbLY5zuvxUuJQaB0AEsev71iV16A61nDS0ZVWJ13jyNZFFLs2vXnsmq4BaLAhispGJvWG16AWoO6rvLm5pygW+1w48PL+bC4Y9HVVHo6L1875p9A6YIvzXXO/JvVgSXMP+cjyR7JNjk3/6MB0mXc2/Wt1DUCDDVEs9rlQb3ib1QJk9lWOwUYu1bVu3+vvNfw+qheZ6e992AACbvjNqqxGW//2XzWcdDpItUOucYiUySdPoE0KZevs6Ce2JWcji6cHjLNdVaFj2hglY58D+w4eM87qHJ11T3aS/9/ZfxJaB2xxcUr3n0rv5azm/Z1Vkdu+g8eDj08Z8468efIQcG+TA2ExYaQDYoeJQ0+8YJTYQe3i5Pz6iVk2dUw2cqnDR17Y2/D7+re/nh8yH8EGEHDDbzdtM/LQ6GucRErA+BCA83c+mBevPdR44S4L5+EIFsvzk7uzzXGTpvf6yueNI0nZx2avYdYzeZivm3dpbNq8SzM/NvPjoXXAFuu/8Y1PXJw2X77/hh6ayzY5aZSAcZ13piEhdLUpNzm33pOUfS5UiU+0eWn0fVQwXHqYhQanZiOXuhRMk82xih0e3rAVG0DADb/bsd8oC42utDrpGoc4/NDPs81xkybt1DPYpi5eTDZyqUvB7Hqz/vd58HCkJuJEvTl+r/7mWD/8Zy1LVsR/PWd500MAfS3z5NwdfFxKm3fkITc4BPTvOuCUIBXMPpfXVXUPm/RZH3x6R/ZceoifHZ2adujwkRWNw0cqVRh2JasdQCT48NAxo2zXyjVO41jBmOgqALpEw+oGpWDIkzNtXnNPSKQ2cjm0bksmQk+9Uv+9HTqZJ9I0vyaMzT4X6uzFBlmgOjt6ycPJivhvlq3P7NzzVnM7TbLpI6LrvLswK09gOFS/FIzy5Ayt25qcfWxqz/f8hno5vHqTcamp6GxkkuLwpV72NA4fUfoysOdgstoBRIKPhs9nJ/RbGhRp7cBrHLkg973TNPFFFzdtcqKN1UYudZ3EBzbV/x513bOs8XVPjPa5sOI53ln3e/Q1ztpnkhXx3z75fNNDAHnPpZ0/ezr4uJQ570aWbWh6YzL8wEanOnch7XOhrpPYoGi+rqe5n19zNjnt6DXrJEQF1eXf5uj7yWoHEAlogaiaQvVaddFVVsdd4xBVq64bFtRdkKYxLdHayKTuedqgT+fQ43nAt2F7o5jsc6G+vmqw6VGV/Ae3vZqsiH/4anaF2ahVl2kYRWx0nXc6MUysgXrfU9nk2PfIDm2fC1XMdH+9IuLkcBCaK1sHnjJoNRihjVxS0ksWPnKmtk1H39f1Asmu0BoAJA5aIHQN1Siey6oockT0IQDNkh0o89ckcDdmG1lUdSF/VL8upC7/wcwADmqfA4vXu/W+R8WN9r11PFkR//2ZrAB6o9ZepBmmRZFjouu8a1oOiDY5Ny40Loocm30urCQU1q6aoONjHR0OKWqHDh+pE1ah40aFtmADCDiDFshwXqutXoavj4DcEPQhANSjUy7IHW/U/nruyaFagKnayCWFDTTyHFMR7eyq52SS9rHfs0p8mFmnhEUhSeDcB0PJivhHv/+9rJPZKMlHl1Jqki0eG13nHV1vys1xnRaI2pPTKPQmYvtcOLBtb8O6qaS18ut3r0/WRi61x/zp2h5znSksntnYAALOoAWi61bVOa2OrMhrub3QvL1VTPQhAKpVU73NcahCrj5t5PL8nQ9lm+NarZpMy6FEbB+bwl4dVnFk/FWO6o17Yd6qpEWcxoVKnWTFa8dfY9I1lrqucpkDIeg87yjZYXr9uGl9q7LoZ2na50DSyizZ4b6aX9ebHINuOrHayKVqm0j1U2t9Xd+qiGd2ytoBRAJaIH2HT+YlKWrXo9KneIPm5jHRhwBQxfq6C5JEPlAhV582cqlPqz/fPu5rNt1CYrXPhSP3rNdCXf21wS2V7PKURZzGZURla27dNc5OfbC8Z0Pw8Qgx7/ThsEYNTFozIW9Vgq6r3kKZnBqZwNrh8KJbe7wUtUO1IK1XAJtqRqrs8pS1A4gEcoGcrR90WznFL+m8U/zZEdm9oF6ck97kGHR9iNlGLhudVgee25M94Bw7x6Qo4kSd5fvwM+O+NlzYNKUs4jQujUolURKMtJPZBjAkvYSPqM4Oz4+/OQl9qxJ6XemyYjU2x8X42JRtZJFuD26uc3uQx12rpMSUtQOIBGqBUDanvM577fKuF/oUv6wzT/HZVU7ek7Jqc6xjI9c0qBOYgo3c1z6kTqvjg7W1d7BBiZDY7XNh377D+TXveA9o8do0ZRGncel/vXKdPc5O1QVmH7+URyj6mHc09+t5+XS2Z6BbldDrig4MNbPDhcbKOoHTa3sHU7KRS/KY17o9oI5UMmxgwRptX2gNABKHWiD1rvM6/RRPPL8wbwm3+/Isad3YvMYJPzUbWaTT6k2LsgdZVb9k8pjKh/+vGjc2j9o+F54ZlMVu5cHhdCE84LLYsIGkRVyOy5n8Oq/6gU2JLvJBPl/+LYKPR4B5R3O/1u2B7nM7Y1GwW5XQ60rdEFQnglAlCrnJcWgBF4uNXOrbg6oyUvpAkX8+Ze0AIoFaIDrW7a51l006fYp3KMgZir4EQNez2/CLyudp8/PjpToeI3UbuaRMvSxep5IFTVnB8qrixoXOD7jQ9rlQ1Xmjvqbqc6rHqYqNTFnE1bgojSj2zKbEoGZ1ImOmt9uDGxdkpV6OndWfp4oBPrJcg9vn8vp5lyDS0KJGDK3f2rR+Yio2cqkaEFTfHqiKFCo2MmXtACKBXiDHz1UCc1XW2umCO75DT/FE5XovJjSo+L96iTOp2cilSmggb6j6HAmUrwdcaPtcSC2+quud6QdcXjcyZRFX46KLHq+vtDTTmZzry29z5oO+5l31Q1t+7t7H6ibOpGYfm3SAzhMaihUU9GGiKhQpSRu5pNuD6VW3B1RVQSUcnjin7QutAUAJuPrqq783ceLErzT7vkmTJl0/efLkrwvOEv/+vMnvLi4QHQe464D8WMX/0RVo8EURUgDEgqSCx0VvH3W3kO74teOD/JO0kfv6eZKQ9PblV4AqA9bHAy60fS7s35nVM7swP4+PEw89HeCed39opYi3UjcIalxUVxjZDjH35lBMoNSSnbXrZ8ZOX/NOJcnoTGh6uOdewVolglKzz4WUICUPCXmnIO0VpOLyHhwOMdjI5fmFa7KDQ15Ev3/ngXEedWwA2x+fFIL8fSHke4Q4/2OjbxTf92XxfSvo3+L/nxPf/6jJCxQXiIo9UJ4bVcU/RK9KH/QpAJToocVKbHRUEHfx2it1G7lUSQ3Sy0Ge5GnzJNVJNXX72KSDw4wsRpKyycmrUX3t1SIRb7luEPS4FMIh+l47LGw9VolxS/DmwOu8K64H8W8ValMrOShJ+xyoblZkEpnQVOVJHl7zVNvYyOXAL3ZnG768m5DyJBeT6rAB7BAIUb6/mZAL8f6REPPvFn7mpMnvvmyBiAc2NaIey+PddGNqh36MIelTAJSXg1LwVWKMLGQauDRODCI38EJW2Z+6Hqg+n756I8dgnwuH127RXnQVEzi46aXL7HPVh3popW4QLjs8bnwxs1PYqJKmhtZtCf73j2HeFdcErRF5WNq2t23sY5M84j0rdWIDaWvRO94WNnJJ2dC1nsWFtoHYAHYITIRcfH2R4LcLH5/47Gc/+wfNfjctkL6+bDLJbOBHs84XikObX9JfS41kV7V9LlSxO4oD219vOxtZ/GDo0mje9k1ukqffcanv8Kn2sc/l/R99X2dKZ/U0F186d/LcZfb50Ig6mtAy3SBcNi7CJlW/TNopbCbbQ//9Y5h3VGifYrr030asFVoz7WKfC0lDi5pKGttuNnJJz97i34aezdX2uWoEkAAMT/JLxUn+m4WPeydMmPAp29ea+bGZHx+bOnfxxandh8Sp43b6mPOe2xFD18z9zNjU7jVjXd0nR6d0/3fo9xMTxq7t+fxYV88rgvtGp8z519DvJyaM/aD7e351SQAAA/pJREFUH8S82S64//zU7r8o63XL1A0C2UY2Slu75nyZ8zvaFbQmaG3INSLWSuj3ExNIS0lTSVtJY0O/n1iQPYt7bs+exXMX41nchhCC+1Uh0jsFdxS4sxiLY3GV853Cx6db+b4BAAgH6AYAAEAHoJaQC9G+qvixEO4v0Wme/j1x4kTx7ZM3lvkeAQCIC9ANAACAhCEE+xohygcEV4l/fy3/9BXi43fFx5+u+t45Qsy/Jdh91VVXTSr/3QIAEAOgGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEnh6quv/t7EiRO/UvzcpEmTrp88efLXBWeJf7dF1Xph51+K/32C2ly1S6mLdhynarTjuBGq111qY9kpukFoxznYrmOl0I5jppC6dgBx4JNisnxfTKY9xWKx4nNfFp9bQf8W//9csbNAyhB27BP29Ak+PmHChCtDvx9XtOs4VaPdxu1jNdZdYmPZUbpBaLc52M5jpdBuY5Yjde0AYkN1t4C8NdR3C18/Gead+YWw6z9DvwefaNdxqka7jZtCcd2lOJadohuEdpuD7TxWCu02ZkWkrh1ARKgWcvHvRYLfLnx8gtzoYd6dP+RdDv5F/P/GL3zhC38e+v24ol3HqRrtNm4KxXWX4lh2im4Q2m0OtvNYKbTbmBWRunYAEaHGSX6pOFF8s/Bx74QJEz4V5t15xRX0nyuvvPIPhb07Q78ZV7TxOFWjrcZNoeoUn9xYdpBuENpqDrb5WCm01ZgVkbp2ACVBTIav0uQX3FHgzmKcQJ2rnO8UPj5d9vvmoI6txEfFSfDfxNd/mn/rx8XnRoO+WQ9IdZxskI/bHfmHbTFuCjWucaIZy07SDQK0I52xMkE76wYhZu0AEkMNIf8SnSro3xMnThRfmrwx3LvzAyEI/yxs+Xv69xe/+MU/EzZtDf2eXNGO41SNdhw3hSoRT24sO0E3CO04B9t1rBTaccyKSF07gEggTg7XiAlzQHCV+PfXCp+fIybVt/I4irZIoadAWTopCVtvbZessHYcp2q06biNW3cpjWUn6QahTedgW46VQjuOGSF17QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAcvD/4IFhcmlqZkwAAAAASUVORK5CYII=\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Gridify example, forced height\n",
|
|
"# If the default gridify layout is not fitting well, you can force the height\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"b\")\n",
|
|
" figure.set_grid(height=2)\n",
|
|
" \n",
|
|
"# Gridify example, forced width\n",
|
|
"# … or the width\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"b\")\n",
|
|
" figure.set_grid(width=2)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 28,
|
|
"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": [
|
|
"# You can also specify a grid directly in the constructor\n",
|
|
"with replot.Figure(\n",
|
|
" grid={\n",
|
|
" \"width\": 2, \n",
|
|
" \"height\": 1, \n",
|
|
" \"grid\": [\n",
|
|
" ((0, 0), \"a\", (1, 1)),\n",
|
|
" ((0, 1), \"b\", (1, 1))\n",
|
|
" ]}) as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"b\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 29,
|
|
"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": [
|
|
"# You can also specify a grid directly in the constructor\n",
|
|
"# Setting the grid to False ignores the groups you may have defined.\n",
|
|
"with replot.Figure(\n",
|
|
" grid=False) as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.sin, (-10, 10), group=\"b\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 30,
|
|
"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": [
|
|
"# Note that if we use legend, xlabel or ylabel with subplots,\n",
|
|
"# they will be set identically on every subplot\n",
|
|
"with replot.Figure(xlabel=\"some x label\", ylabel=\"some y label\") as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\", label=\"cos\")\n",
|
|
" figure.plot(np.sin, (-10, 10), group=\"ç\", label=\"sin\")\n",
|
|
" figure.set_grid([\"aç\"])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 31,
|
|
"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": [
|
|
"# You can avoid it by passing dict for these arguments\n",
|
|
"# they will be set identically on every subplot\n",
|
|
"with replot.Figure(xlabel={\"a\": \"some x label\", \"ç\": \"\"},\n",
|
|
" ylabel={\"a\": \"\", \"ç\": \"some y label\"},\n",
|
|
" legend={\"a\": False}) as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\", label=\"cos\")\n",
|
|
" figure.plot(np.sin, (-10, 10), group=\"ç\", label=\"sin\")\n",
|
|
" figure.set_grid([\"aç\"])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Saving figures"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 32,
|
|
"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": [
|
|
"# Save a figure to a file\n",
|
|
"with replot.Figure(savepath=\"/tmp/out.png\") as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 33,
|
|
"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": [
|
|
"# or equivalently\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10))\n",
|
|
" figure.savepath = \"/tmp/out.png\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Some errors you might encounter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 34,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"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-34-810be42c9f1a>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# Invalid interval for plotting a function\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\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----> 3\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 314\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 315\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--> 316\u001b[1;33m \u001b[0mplot_\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 317\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 318\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(data, *args, **kwargs)\u001b[0m\n\u001b[0;32m 744\u001b[0m raise exc.InvalidParameterError(\n\u001b[0;32m 745\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--> 746\u001b[1;33m \"specifying plotting interval.\")\n\u001b[0m\u001b[0;32m 747\u001b[0m \u001b[1;32mreturn\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[0m\n\u001b[0;32m 748\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": [
|
|
"# Invalid interval for plotting a function\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.sin, None)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 35,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"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-35-bb8eaf706fb0>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# Invalid plot call, no arguments given\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\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----> 3\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 303\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 304\u001b[0m raise exc.InvalidParameterError(\n\u001b[1;32m--> 305\u001b[1;33m \"You should pass at least one argument to this function.\")\n\u001b[0m\u001b[0;32m 306\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 307\u001b[0m \u001b[1;31m# Extract custom kwargs (the ones from replot but not matplotlib) from\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": [
|
|
"# Invalid plot call, no arguments given\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 36,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"ename": "InvalidParameterError",
|
|
"evalue": "Group name cannot be longer than one unicode character.",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[1;31mInvalidParameterError\u001b[0m Traceback (most recent call last)",
|
|
"\u001b[1;32m<ipython-input-36-8b04957bf3f0>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# Invalid group argument, groups are one unicode character long\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\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----> 3\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[0mcos\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m10\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mgroup\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m\"abc\"\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 308\u001b[0m \u001b[1;31m# kwargs\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 309\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mkwargs\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 310\u001b[1;33m \u001b[0mkwargs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcustom_kwargs\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_handle_custom_plot_arguments\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 311\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 312\u001b[0m \u001b[0mcustom_kwargs\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m{\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_handle_custom_plot_arguments\u001b[1;34m(kwargs)\u001b[0m\n\u001b[0;32m 697\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m\"group\"\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m>\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 698\u001b[0m raise exc.InvalidParameterError(\n\u001b[1;32m--> 699\u001b[1;33m \"Group name cannot be longer than one unicode character.\")\n\u001b[0m\u001b[0;32m 700\u001b[0m \u001b[1;32melif\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m\"group\"\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m==\u001b[0m \u001b[0m_DEFAULT_GROUP\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 701\u001b[0m raise exc.InvalidParameterError(\n",
|
|
"\u001b[1;31mInvalidParameterError\u001b[0m: Group name cannot be longer than one unicode character."
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Invalid group argument, groups are one unicode character long\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"abc\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 37,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"ename": "AttributeError",
|
|
"evalue": "'Figure' object has no attribute 'apply_grid'",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)",
|
|
"\u001b[1;32m<ipython-input-37-c89b5aaa14ef>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 2\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[0;32m 3\u001b[0m \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[0mcos\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m10\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mgroup\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m\"a\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0mfigure\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mapply_grid\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[0m\n\u001b[0m",
|
|
"\u001b[1;31mAttributeError\u001b[0m: 'Figure' object has no attribute 'apply_grid'"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Invalid grid, no grid provided\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.apply_grid([])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 38,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"ename": "AttributeError",
|
|
"evalue": "'Figure' object has no attribute 'apply_grid'",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)",
|
|
"\u001b[1;32m<ipython-input-38-c6ca6527d69a>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 2\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[0;32m 3\u001b[0m \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[0mcos\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m10\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mgroup\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m\"a\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m figure.apply_grid([\"a\",\n\u001b[0m\u001b[0;32m 5\u001b[0m \"ba\"])\n",
|
|
"\u001b[1;31mAttributeError\u001b[0m: 'Figure' object has no attribute 'apply_grid'"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Invalid grid, not a rectangular one\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.apply_grid([\"a\",\n",
|
|
" \"ba\"])"
|
|
]
|
|
}
|
|
],
|
|
"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
|
|
}
|