diff --git a/examples/widgets/D3.ipynb b/examples/widgets/D3.ipynb deleted file mode 100644 index 71ab413..0000000 --- a/examples/widgets/D3.ipynb +++ /dev/null @@ -1,1581 +0,0 @@ -{ - "metadata": { - "name": "" - }, - "nbformat": 3, - "nbformat_minor": 0, - "worksheets": [ - { - "cells": [ - { - "cell_type": "code", - "collapsed": false, - "input": [ - "from __future__ import print_function # py 2.7 compat\n", - "\n", - "import networkx as nx" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 1 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This notebook demonstrates how NetworkX and D3 can be married using custom widget code." - ] - }, - { - "cell_type": "heading", - "level": 1, - "metadata": {}, - "source": [ - "Hooking NetworkX Graphs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "NetworkX graphs do not have events that can be listened to. In order to watch the NetworkX graph object for changes a custom eventful graph object must be created. The custom eventful graph object will inherit from the base graph object and use special eventful dictionaries instead of standard Python dict instances. Because NetworkX nests dictionaries inside dictionaries, it's important that the eventful dictionary is capable of recognizing when a dictionary value is set to another dictionary instance. When this happens, the eventful dictionary needs to also make the new dictionary an eventful dictionary. This allows the eventful dictionary to listen to changes made to dictionaries within dictionaries." - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "class EventfulDict(dict):\n", - " \n", - " def __init__(self, *args, **kwargs):\n", - " self._add_callbacks = []\n", - " self._del_callbacks = []\n", - " self._set_callbacks = []\n", - " dict.__init__(self, *args, **kwargs)\n", - " \n", - " def on_add(self, callback, remove=False):\n", - " self._register_callback(self._add_callbacks, callback, remove)\n", - " def on_del(self, callback, remove=False):\n", - " self._register_callback(self._del_callbacks, callback, remove)\n", - " def on_set(self, callback, remove=False):\n", - " self._register_callback(self._set_callbacks, callback, remove)\n", - " def _register_callback(self, callback_list, callback, remove=False):\n", - " if callable(callback):\n", - " if remove and callback in callback_list:\n", - " callback_list.remove(callback)\n", - " elif not remove and not callback in callback_list:\n", - " callback_list.append(callback)\n", - " else:\n", - " raise Exception('Callback must be callable.')\n", - "\n", - " def _handle_add(self, key, value):\n", - " self._try_callbacks(self._add_callbacks, key, value)\n", - " def _handle_del(self, key):\n", - " self._try_callbacks(self._del_callbacks, key)\n", - " def _handle_set(self, key, value):\n", - " self._try_callbacks(self._set_callbacks, key, value)\n", - " def _try_callbacks(self, callback_list, *pargs, **kwargs):\n", - " for callback in callback_list:\n", - " callback(*pargs, **kwargs)\n", - " \n", - " def __setitem__(self, key, value):\n", - " return_val = None\n", - " exists = False\n", - " if key in self:\n", - " exists = True\n", - " \n", - " # If the user sets the property to a new dict, make the dict\n", - " # eventful and listen to the changes of it ONLY if it is not\n", - " # already eventful. Any modification to this new dict will\n", - " # fire a set event of the parent dict.\n", - " if isinstance(value, dict) and not isinstance(value, EventfulDict):\n", - " new_dict = EventfulDict(value)\n", - " \n", - " def handle_change(*pargs, **kwargs):\n", - " self._try_callbacks(self._set_callbacks, key, dict.__getitem__(self, key))\n", - " \n", - " new_dict.on_add(handle_change)\n", - " new_dict.on_del(handle_change)\n", - " new_dict.on_set(handle_change)\n", - " return_val = dict.__setitem__(self, key, new_dict)\n", - " else:\n", - " return_val = dict.__setitem__(self, key, value)\n", - " \n", - " if exists:\n", - " self._handle_set(key, value)\n", - " else:\n", - " self._handle_add(key, value)\n", - " return return_val\n", - " \n", - "\n", - " def __delitem__(self, key):\n", - " return_val = dict.__delitem__(self, key)\n", - " self._handle_del(key)\n", - " return return_val\n", - "\n", - " \n", - " def pop(self, key):\n", - " return_val = dict.pop(self, key)\n", - " if key in self:\n", - " self._handle_del(key)\n", - " return return_val\n", - "\n", - " def popitem(self):\n", - " popped = dict.popitem(self)\n", - " if popped is not None and popped[0] is not None:\n", - " self._handle_del(popped[0])\n", - " return popped\n", - "\n", - " def update(self, other_dict):\n", - " for (key, value) in other_dict.items():\n", - " self[key] = value\n", - " \n", - " def clear(self):\n", - " for key in list(self.keys()):\n", - " del self[key]" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 2 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Override the NetworkX Graph object to make an eventful graph." - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "class EventfulGraph(nx.Graph):\n", - " \n", - " def __init__(self, *pargs, **kwargs):\n", - " \"\"\"Initialize a graph with edges, name, graph attributes.\"\"\"\n", - " super(EventfulGraph, self).__init__(*pargs, **kwargs)\n", - " \n", - " self.graph = EventfulDict(self.graph)\n", - " self.node = EventfulDict(self.node)\n", - " self.adj = EventfulDict(self.adj)\n", - " " - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 3 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To make sure that the eventful graph works, create a new graph and log the dictionary events raised." - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "def echo_dict_events(eventful_dict, prefix=''):\n", - " def key_add(key, value):\n", - " print(prefix + 'add (%s, %s)' % (key, str(value)))\n", - " def key_set(key, value):\n", - " print(prefix + 'set (%s, %s)' % (key, str(value)))\n", - " def key_del(key):\n", - " print(prefix + 'del %s' % key)\n", - " eventful_dict.on_add(key_add)\n", - " eventful_dict.on_set(key_set)\n", - " eventful_dict.on_del(key_del)\n", - " \n", - "def echo_graph_events(eventful_graph):\n", - " for key in ['graph', 'node', 'adj']:\n", - " echo_dict_events(getattr(eventful_graph, key), prefix=key+' ')" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 4 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "G = EventfulGraph()\n", - "echo_graph_events(G)\n", - "\n", - "G.add_node('hello')\n", - "G.add_node('goodbye', fill=\"red\")\n", - "G.add_edges_from([(1,2),(1,3), (1,'goodbye')], stroke=\"lime\")" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "adj add (hello, {})\n", - "node add (hello, {})\n", - "adj add (goodbye, {})\n", - "node add (goodbye, {'fill': 'red'})\n", - "adj add (1, {})\n", - "node add (1, {})\n", - "adj add (2, {})\n", - "node add (2, {})\n", - "adj set (1, {2: {'stroke': 'lime'}})\n", - "adj set (2, {1: {'stroke': 'lime'}})\n", - "adj add (3, {})\n", - "node add (3, {})\n", - "adj set (1, {2: {'stroke': 'lime'}, 3: {'stroke': 'lime'}})\n", - "adj set (3, {1: {'stroke': 'lime'}})\n", - "adj set (1, {2: {'stroke': 'lime'}, 3: {'stroke': 'lime'}, 'goodbye': {'stroke': 'lime'}})\n", - "adj set (goodbye, {1: {'stroke': 'lime'}})\n" - ] - } - ], - "prompt_number": 5 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "G.adj" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 6, - "text": [ - "{1: {2: {'stroke': 'lime'},\n", - " 3: {'stroke': 'lime'},\n", - " 'goodbye': {'stroke': 'lime'}},\n", - " 2: {1: {'stroke': 'lime'}},\n", - " 3: {1: {'stroke': 'lime'}},\n", - " 'goodbye': {1: {'stroke': 'lime'}},\n", - " 'hello': {}}" - ] - } - ], - "prompt_number": 6 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "G.node" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 7, - "text": [ - "{1: {}, 2: {}, 3: {}, 'goodbye': {'fill': 'red'}, 'hello': {}}" - ] - } - ], - "prompt_number": 7 - }, - { - "cell_type": "heading", - "level": 1, - "metadata": {}, - "source": [ - "D3 Widget" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The D3 widget will blindly port all of the dictionary events over custom widget messages." - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "from IPython.html import widgets # Widget definitions\n", - "from IPython.display import display # Used to display widgets in the notebook" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 8 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "# Import the base Widget class and the traitlets Unicode class.\n", - "from IPython.html.widgets import Widget\n", - "from IPython.utils.traitlets import Unicode, Int\n", - "\n", - "# Define our ForceDirectedGraphWidget and its target model and default view.\n", - "class ForceDirectedGraphWidget(Widget):\n", - " target_name = Unicode('ForceDirectedGraphModel')\n", - " default_view_name = Unicode('D3ForceDirectedGraphView')\n", - " \n", - " _keys = ['width', 'height']\n", - " width = Int(400)\n", - " height = Int(300)\n", - " \n", - " def __init__(self, eventful_graph, *pargs, **kwargs):\n", - " Widget.__init__(self, *pargs, **kwargs)\n", - " \n", - " self._eventful_graph = eventful_graph\n", - " self._send_dict_changes(eventful_graph.graph, 'graph')\n", - " self._send_dict_changes(eventful_graph.node, 'node')\n", - " self._send_dict_changes(eventful_graph.adj, 'adj')\n", - " \n", - " \n", - " def _repr_widget_(self, *pargs, **kwargs):\n", - " \n", - " # Show the widget, then send the current state\n", - " Widget._repr_widget_(self, *pargs, **kwargs)\n", - " for (key, value) in self._eventful_graph.graph.items():\n", - " self.send({'dict': 'graph', 'action': 'add', 'key': key, 'value': value})\n", - " for (key, value) in self._eventful_graph.node.items():\n", - " self.send({'dict': 'node', 'action': 'add', 'key': key, 'value': value})\n", - " for (key, value) in self._eventful_graph.adj.items():\n", - " self.send({'dict': 'adj', 'action': 'add', 'key': key, 'value': value})\n", - " \n", - " \n", - " def _send_dict_changes(self, eventful_dict, dict_name):\n", - " def key_add(key, value):\n", - " self.send({'dict': dict_name, 'action': 'add', 'key': key, 'value': value})\n", - " def key_set(key, value):\n", - " self.send({'dict': dict_name, 'action': 'set', 'key': key, 'value': value})\n", - " def key_del(key):\n", - " self.send({'dict': dict_name, 'action': 'del', 'key': key})\n", - " eventful_dict.on_add(key_add)\n", - " eventful_dict.on_set(key_set)\n", - " eventful_dict.on_del(key_del)\n", - " " - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 9 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The front-end listens to the dictionary events and keeps the D3 control in sync with the dictionary in the back-end." - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "%%javascript\n", - "\n", - "require([\"http://d3js.org/d3.v3.min.js\", \"notebook/js/widget\"], function(){\n", - " \n", - " // Define the ForceDirectedGraphModel and register it with the widget manager.\n", - " var ForceDirectedGraphModel = IPython.WidgetModel.extend({});\n", - " IPython.widget_manager.register_widget_model('ForceDirectedGraphModel', ForceDirectedGraphModel);\n", - " \n", - " // Define the D3ForceDirectedGraphView\n", - " var D3ForceDirectedGraphView = IPython.WidgetView.extend({\n", - " \n", - " render: function(){\n", - " this.guid = 'd3force' + IPython.utils.uuid();\n", - " this.setElement($('
', {id: this.guid}));\n", - " this.model.on_msg($.proxy(this.handle_msg, this));\n", - " this.has_drawn = false;\n", - " },\n", - " \n", - " try_add_node: function(id){\n", - " var index = this.find_node(id);\n", - " if (index == -1) {\n", - " var node = {id: id};\n", - " this.nodes.push(node);\n", - " return node;\n", - " } else {\n", - " return this.nodes[index];\n", - " }\n", - " },\n", - " \n", - " update_node: function(node, attributes) {\n", - " if (node !== null) {\n", - " for (var key in attributes) {\n", - " node[key] = attributes[key];\n", - " }\n", - " this._update_node(d3.select('#' + this.guid + node.id));\n", - " }\n", - " },\n", - " \n", - " remove_node: function(id){\n", - " this.remove_links_to(id);\n", - " \n", - " var found_index = this.find_node(id);\n", - " if (found_index>=0) {\n", - " this.nodes.splice(found_index, 1);\n", - " }\n", - " },\n", - " \n", - " find_node: function(id){\n", - " var found_index = -1;\n", - " for (var index in this.nodes) {\n", - " if (this.nodes[index].id == id) {\n", - " found_index = index;\n", - " break;\n", - " }\n", - " }\n", - " return found_index;\n", - " },\n", - " \n", - " find_link: function(source_id, target_id){\n", - " for (var index in this.links) {\n", - " if (this.links[index].source.id == source_id && this.links[index].target.id == target_id) {\n", - " return index;\n", - " }\n", - " }\n", - " return -1;\n", - " },\n", - " \n", - " try_add_link: function(source_id, target_id){\n", - " var index = this.find_link(source_id, target_id);\n", - " if (index == -1) {\n", - " var source_node = this.try_add_node(source_id);\n", - " var target_node = this.try_add_node(target_id);\n", - " var new_link = {source: source_node, target: target_node};\n", - " this.links.push(new_link);\n", - " return new_link;\n", - " } else {\n", - " return this.links[index]\n", - " }\n", - " },\n", - " \n", - " update_link: function(link, attributes){\n", - " if (link != null) {\n", - " for (var key in attributes) {\n", - " link[key] = attributes[key];\n", - " }\n", - " this._update_edge(d3.select('#' + this.guid + link.source.id + \"-\" + link.target.id));\n", - " }\n", - " },\n", - " \n", - " remove_links: function(source_id){\n", - " var found_indicies = [];\n", - " for (var index in this.links) {\n", - " if (this.links[index].source.id == source_id) {\n", - " found_indicies.push(index);\n", - " }\n", - " }\n", - " found_indicies.reverse();\n", - " \n", - " for (var index in found_indicies) {\n", - " this.links.splice(index, 1);\n", - " };\n", - " },\n", - " \n", - " remove_links_to: function(id){\n", - " var found_indicies = [];\n", - " for (var index in this.links) {\n", - " if (this.links[index].source.id == id || this.links[index].target.id == id) {\n", - " found_indicies.push(index);\n", - " }\n", - " }\n", - " found_indicies.reverse();\n", - " \n", - " for (var index in found_indicies) {\n", - " this.links.splice(index, 1);\n", - " };\n", - " },\n", - " \n", - " handle_msg: function(content){\n", - " var dict = content.dict;\n", - " var action = content.action;\n", - " var key = content.key;\n", - " \n", - " if (dict=='node') {\n", - " if (action=='add' || action=='set') {\n", - " this.update_node(this.try_add_node(key), content.value)\n", - " } else if (action=='del') {\n", - " this.remove_node(key);\n", - " }\n", - " \n", - " } else if (dict=='adj') {\n", - " if (action=='add' || action=='set') {\n", - " var links = content.value;\n", - " for (var target_id in links) {\n", - " this.update_link(this.try_add_link(key, target_id), links[target_id]);\n", - " }\n", - " } else if (action=='del') {\n", - " this.remove_links(key);\n", - " }\n", - " }\n", - " this.start();\n", - " },\n", - " \n", - " start: function() {\n", - " var node = this.svg.selectAll(\".node\"),\n", - " link = this.svg.selectAll(\".link\");\n", - " \n", - " var link = link.data(this.force.links(), function(d) { return d.source.id + \"-\" + d.target.id; });\n", - " this._update_edge(link.enter().insert(\"line\", \".node\"))\n", - " link.exit().remove();\n", - " \n", - " var node = node.data(this.force.nodes(), function(d) { return d.id;});\n", - " var that = this;\n", - " this._update_node(node.enter().append(\"circle\"));\n", - " node.exit().remove();\n", - " \n", - " this.force.start();\n", - " },\n", - " \n", - " _update_node: function(node) {\n", - " var that = this;\n", - " node\n", - " .attr(\"id\", function(d) { return that.guid + d.id; })\n", - " .attr(\"class\", function(d) { return \"node \" + d.id; })\n", - " .attr(\"r\", function(d) {\n", - " if (d.r == undefined) {\n", - " return 8; \n", - " } else {\n", - " return d.r;\n", - " }\n", - " \n", - " })\n", - " .style(\"fill\", function(d) {\n", - " if (d.fill == undefined) {\n", - " return that.color(d.group); \n", - " } else {\n", - " return d.fill;\n", - " }\n", - " \n", - " })\n", - " .style(\"stroke\", function(d) {\n", - " if (d.stroke == undefined) {\n", - " return \"#FFF\"; \n", - " } else {\n", - " return d.stroke;\n", - " }\n", - " \n", - " })\n", - " .style(\"stroke-width\", function(d) {\n", - " if (d.strokewidth == undefined) {\n", - " return \"#FFF\"; \n", - " } else {\n", - " return d.strokewidth;\n", - " }\n", - " \n", - " })\n", - " .call(this.force.drag);\n", - " },\n", - " \n", - " _update_edge: function(edge) {\n", - " var that = this;\n", - " edge\n", - " .attr(\"id\", function(d) { return that.guid + d.source.id + \"-\" + d.target.id; })\n", - " .attr(\"class\", \"link\")\n", - " .style(\"stroke-width\", function(d) {\n", - " if (d.strokewidth == undefined) {\n", - " return \"1.5px\"; \n", - " } else {\n", - " return d.strokewidth;\n", - " }\n", - " \n", - " })\n", - " .style('stroke', function(d) {\n", - " if (d.stroke == undefined) {\n", - " return \"#999\"; \n", - " } else {\n", - " return d.stroke;\n", - " }\n", - " \n", - " });\n", - " },\n", - " \n", - " tick: function() {\n", - " var node = this.svg.selectAll(\".node\"),\n", - " link = this.svg.selectAll(\".link\");\n", - " \n", - " link.attr(\"x1\", function(d) { return d.source.x; })\n", - " .attr(\"y1\", function(d) { return d.source.y; })\n", - " .attr(\"x2\", function(d) { return d.target.x; })\n", - " .attr(\"y2\", function(d) { return d.target.y; });\n", - " \n", - " node.attr(\"cx\", function(d) { return d.x; })\n", - " .attr(\"cy\", function(d) { return d.y; });\n", - " },\n", - " \n", - " update: function(){\n", - " if (!this.has_drawn) {\n", - " this.has_drawn = true;\n", - " \n", - " var width = this.model.get('width'),\n", - " height = this.model.get('height');\n", - " \n", - " this.color = d3.scale.category20();\n", - " \n", - " this.nodes = [];\n", - " this.links = [];\n", - " \n", - " this.force = d3.layout.force()\n", - " .nodes(this.nodes)\n", - " .links(this.links)\n", - " .charge(function (d) {\n", - " if (d.charge === undefined) {\n", - " return -120;\n", - " } else {\n", - " return d.charge;\n", - " }\n", - " })\n", - " .linkDistance(function (d) {\n", - " if (d.distance === undefined) {\n", - " return 40;\n", - " } else {\n", - " return d.distance;\n", - " }\n", - " })\n", - " .linkStrength(function (d) {\n", - " if (d.strength === undefined) {\n", - " return 1.0;\n", - " } else {\n", - " return d.strength;\n", - " }\n", - " })\n", - " .size([width, height])\n", - " .on(\"tick\", $.proxy(this.tick, this));\n", - " \n", - " this.svg = d3.select(\"#\" + this.guid).append(\"svg\")\n", - " .attr(\"width\", width)\n", - " .attr(\"height\", height);\n", - " \n", - " var that = this;\n", - " setTimeout(function() {\n", - " that.start();\n", - " }, 0);\n", - " }\n", - " \n", - " return IPython.WidgetView.prototype.update.call(this);\n", - " },\n", - " \n", - " });\n", - " \n", - " // Register the D3ForceDirectedGraphView with the widget manager.\n", - " IPython.widget_manager.register_widget_view('D3ForceDirectedGraphView', D3ForceDirectedGraphView);\n", - "});" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "javascript": [ - "\n", - "require([\"http://d3js.org/d3.v3.min.js\", \"notebook/js/widget\"], function(){\n", - " \n", - " // Define the ForceDirectedGraphModel and register it with the widget manager.\n", - " var ForceDirectedGraphModel = IPython.WidgetModel.extend({});\n", - " IPython.widget_manager.register_widget_model('ForceDirectedGraphModel', ForceDirectedGraphModel);\n", - " \n", - " // Define the D3ForceDirectedGraphView\n", - " var D3ForceDirectedGraphView = IPython.WidgetView.extend({\n", - " \n", - " render: function(){\n", - " this.guid = 'd3force' + IPython.utils.uuid();\n", - " this.setElement($('
', {id: this.guid}));\n", - " this.model.on_msg($.proxy(this.handle_msg, this));\n", - " this.has_drawn = false;\n", - " },\n", - " \n", - " try_add_node: function(id){\n", - " var index = this.find_node(id);\n", - " if (index == -1) {\n", - " var node = {id: id};\n", - " this.nodes.push(node);\n", - " return node;\n", - " } else {\n", - " return this.nodes[index];\n", - " }\n", - " },\n", - " \n", - " update_node: function(node, attributes) {\n", - " if (node !== null) {\n", - " for (var key in attributes) {\n", - " node[key] = attributes[key];\n", - " }\n", - " this._update_node(d3.select('#' + this.guid + node.id));\n", - " }\n", - " },\n", - " \n", - " remove_node: function(id){\n", - " this.remove_links_to(id);\n", - " \n", - " var found_index = this.find_node(id);\n", - " if (found_index>=0) {\n", - " this.nodes.splice(found_index, 1);\n", - " }\n", - " },\n", - " \n", - " find_node: function(id){\n", - " var found_index = -1;\n", - " for (var index in this.nodes) {\n", - " if (this.nodes[index].id == id) {\n", - " found_index = index;\n", - " break;\n", - " }\n", - " }\n", - " return found_index;\n", - " },\n", - " \n", - " find_link: function(source_id, target_id){\n", - " for (var index in this.links) {\n", - " if (this.links[index].source.id == source_id && this.links[index].target.id == target_id) {\n", - " return index;\n", - " }\n", - " }\n", - " return -1;\n", - " },\n", - " \n", - " try_add_link: function(source_id, target_id){\n", - " var index = this.find_link(source_id, target_id);\n", - " if (index == -1) {\n", - " var source_node = this.try_add_node(source_id);\n", - " var target_node = this.try_add_node(target_id);\n", - " var new_link = {source: source_node, target: target_node};\n", - " this.links.push(new_link);\n", - " return new_link;\n", - " } else {\n", - " return this.links[index]\n", - " }\n", - " },\n", - " \n", - " update_link: function(link, attributes){\n", - " if (link != null) {\n", - " for (var key in attributes) {\n", - " link[key] = attributes[key];\n", - " }\n", - " this._update_edge(d3.select('#' + this.guid + link.source.id + \"-\" + link.target.id));\n", - " }\n", - " },\n", - " \n", - " remove_links: function(source_id){\n", - " var found_indicies = [];\n", - " for (var index in this.links) {\n", - " if (this.links[index].source.id == source_id) {\n", - " found_indicies.push(index);\n", - " }\n", - " }\n", - " found_indicies.reverse();\n", - " \n", - " for (var index in found_indicies) {\n", - " this.links.splice(index, 1);\n", - " };\n", - " },\n", - " \n", - " remove_links_to: function(id){\n", - " var found_indicies = [];\n", - " for (var index in this.links) {\n", - " if (this.links[index].source.id == id || this.links[index].target.id == id) {\n", - " found_indicies.push(index);\n", - " }\n", - " }\n", - " found_indicies.reverse();\n", - " \n", - " for (var index in found_indicies) {\n", - " this.links.splice(index, 1);\n", - " };\n", - " },\n", - " \n", - " handle_msg: function(content){\n", - " var dict = content.dict;\n", - " var action = content.action;\n", - " var key = content.key;\n", - " \n", - " if (dict=='node') {\n", - " if (action=='add' || action=='set') {\n", - " this.update_node(this.try_add_node(key), content.value)\n", - " } else if (action=='del') {\n", - " this.remove_node(key);\n", - " }\n", - " \n", - " } else if (dict=='adj') {\n", - " if (action=='add' || action=='set') {\n", - " var links = content.value;\n", - " for (var target_id in links) {\n", - " this.update_link(this.try_add_link(key, target_id), links[target_id]);\n", - " }\n", - " } else if (action=='del') {\n", - " this.remove_links(key);\n", - " }\n", - " }\n", - " this.start();\n", - " },\n", - " \n", - " start: function() {\n", - " var node = this.svg.selectAll(\".node\"),\n", - " link = this.svg.selectAll(\".link\");\n", - " \n", - " var link = link.data(this.force.links(), function(d) { return d.source.id + \"-\" + d.target.id; });\n", - " this._update_edge(link.enter().insert(\"line\", \".node\"))\n", - " link.exit().remove();\n", - " \n", - " var node = node.data(this.force.nodes(), function(d) { return d.id;});\n", - " var that = this;\n", - " this._update_node(node.enter().append(\"circle\"));\n", - " node.exit().remove();\n", - " \n", - " this.force.start();\n", - " },\n", - " \n", - " _update_node: function(node) {\n", - " var that = this;\n", - " node\n", - " .attr(\"id\", function(d) { return that.guid + d.id; })\n", - " .attr(\"class\", function(d) { return \"node \" + d.id; })\n", - " .attr(\"r\", function(d) {\n", - " if (d.r == undefined) {\n", - " return 8; \n", - " } else {\n", - " return d.r;\n", - " }\n", - " \n", - " })\n", - " .style(\"fill\", function(d) {\n", - " if (d.fill == undefined) {\n", - " return that.color(d.group); \n", - " } else {\n", - " return d.fill;\n", - " }\n", - " \n", - " })\n", - " .style(\"stroke\", function(d) {\n", - " if (d.stroke == undefined) {\n", - " return \"#FFF\"; \n", - " } else {\n", - " return d.stroke;\n", - " }\n", - " \n", - " })\n", - " .style(\"stroke-width\", function(d) {\n", - " if (d.strokewidth == undefined) {\n", - " return \"#FFF\"; \n", - " } else {\n", - " return d.strokewidth;\n", - " }\n", - " \n", - " })\n", - " .call(this.force.drag);\n", - " },\n", - " \n", - " _update_edge: function(edge) {\n", - " var that = this;\n", - " edge\n", - " .attr(\"id\", function(d) { return that.guid + d.source.id + \"-\" + d.target.id; })\n", - " .attr(\"class\", \"link\")\n", - " .style(\"stroke-width\", function(d) {\n", - " if (d.strokewidth == undefined) {\n", - " return \"1.5px\"; \n", - " } else {\n", - " return d.strokewidth;\n", - " }\n", - " \n", - " })\n", - " .style('stroke', function(d) {\n", - " if (d.stroke == undefined) {\n", - " return \"#999\"; \n", - " } else {\n", - " return d.stroke;\n", - " }\n", - " \n", - " });\n", - " },\n", - " \n", - " tick: function() {\n", - " var node = this.svg.selectAll(\".node\"),\n", - " link = this.svg.selectAll(\".link\");\n", - " \n", - " link.attr(\"x1\", function(d) { return d.source.x; })\n", - " .attr(\"y1\", function(d) { return d.source.y; })\n", - " .attr(\"x2\", function(d) { return d.target.x; })\n", - " .attr(\"y2\", function(d) { return d.target.y; });\n", - " \n", - " node.attr(\"cx\", function(d) { return d.x; })\n", - " .attr(\"cy\", function(d) { return d.y; });\n", - " },\n", - " \n", - " update: function(){\n", - " if (!this.has_drawn) {\n", - " this.has_drawn = true;\n", - " \n", - " var width = this.model.get('width'),\n", - " height = this.model.get('height');\n", - " \n", - " this.color = d3.scale.category20();\n", - " \n", - " this.nodes = [];\n", - " this.links = [];\n", - " \n", - " this.force = d3.layout.force()\n", - " .nodes(this.nodes)\n", - " .links(this.links)\n", - " .charge(function (d) {\n", - " if (d.charge === undefined) {\n", - " return -120;\n", - " } else {\n", - " return d.charge;\n", - " }\n", - " })\n", - " .linkDistance(function (d) {\n", - " if (d.distance === undefined) {\n", - " return 40;\n", - " } else {\n", - " return d.distance;\n", - " }\n", - " })\n", - " .linkStrength(function (d) {\n", - " if (d.strength === undefined) {\n", - " return 1.0;\n", - " } else {\n", - " return d.strength;\n", - " }\n", - " })\n", - " .size([width, height])\n", - " .on(\"tick\", $.proxy(this.tick, this));\n", - " \n", - " this.svg = d3.select(\"#\" + this.guid).append(\"svg\")\n", - " .attr(\"width\", width)\n", - " .attr(\"height\", height);\n", - " \n", - " var that = this;\n", - " setTimeout(function() {\n", - " that.start();\n", - " }, 0);\n", - " }\n", - " \n", - " return IPython.WidgetView.prototype.update.call(this);\n", - " },\n", - " \n", - " });\n", - " \n", - " // Register the D3ForceDirectedGraphView with the widget manager.\n", - " IPython.widget_manager.register_widget_view('D3ForceDirectedGraphView', D3ForceDirectedGraphView);\n", - "});" - ], - "metadata": {}, - "output_type": "display_data", - "text": [ - "" - ] - } - ], - "prompt_number": 10 - }, - { - "cell_type": "heading", - "level": 1, - "metadata": {}, - "source": [ - "Test" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "floating_container = widgets.ContainerWidget(default_view_name='ModalView')\n", - "floating_container.description = \"Dynamic D3 rendering of a NetworkX graph\"\n", - "floating_container.button_text = \"Render Window\"\n", - "floating_container.set_css({\n", - " 'width': '420px',\n", - " 'height': '350px'}, selector='modal')\n", - "\n", - "G = EventfulGraph()\n", - "d3 = ForceDirectedGraphWidget(G, parent=floating_container)\n", - "display(floating_container)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "ename": "KeyError", - "evalue": "'modal'", - "output_type": "pyerr", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 4\u001b[0m floating_container.set_css({\n\u001b[1;32m 5\u001b[0m \u001b[0;34m'width'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'420px'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m 'height': '350px'}, selector='modal')\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0mG\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mEventfulGraph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/Users/grout/projects/ipython-upstream/IPython/html/widgets/widget.pyc\u001b[0m in \u001b[0;36mset_css\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 355\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdict\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 356\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32min\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 357\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_css\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mselector\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mvalue\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_css\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mselector\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 358\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_css\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mselector\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 359\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msend_state\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'_css'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mKeyError\u001b[0m: 'modal'" - ] - } - ], - "prompt_number": 11 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The following code creates an animation of some of the plot's properties." - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "import time\n", - "\n", - "G.add_node(1, fill=\"red\", stroke=\"black\")\n", - "time.sleep(1.0)\n", - "\n", - "G.add_node(2, fill=\"gold\", stroke=\"black\")\n", - "time.sleep(1.0)\n", - "\n", - "G.add_node(3, fill=\"green\", stroke=\"black\")\n", - "time.sleep(1.0)\n", - "\n", - "G.add_edges_from([(1,2),(1,3), (2,3)], stroke=\"#aaa\", strokewidth=\"1px\", distance=200, strength=0.5)\n", - "time.sleep(1.0)\n", - "\n", - "G.adj[1][2]['distance'] = 20\n", - "time.sleep(1.0)\n", - "\n", - "G.adj[1][3]['distance'] = 20\n", - "time.sleep(1.0)\n", - "\n", - "G.adj[2][3]['distance'] = 20\n", - "time.sleep(1.0)\n", - "\n", - "G.node[1]['r'] = 16\n", - "time.sleep(0.3)\n", - "G.node[1]['r'] = 8\n", - "G.node[2]['r'] = 16\n", - "time.sleep(0.3)\n", - "G.node[2]['r'] = 8\n", - "G.node[3]['r'] = 16\n", - "time.sleep(0.3)\n", - "G.node[3]['r'] = 8\n", - "\n", - "G.node[1]['fill'] = 'purple'\n", - "time.sleep(0.3)\n", - "G.node[1]['fill'] = 'red'\n", - "G.node[2]['fill'] = 'purple'\n", - "time.sleep(0.3)\n", - "G.node[2]['fill'] = 'gold'\n", - "G.node[3]['fill'] = 'purple'\n", - "time.sleep(0.3)\n", - "G.node[3]['fill'] = 'green'\n", - "time.sleep(1.0)\n", - "\n", - "G.node.clear()\n", - "time.sleep(1.0)\n", - "\n", - "floating_container.close()\n" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "node set (1, {'stroke': 'black'})\n", - "node set (1, {'stroke': 'black', 'fill': 'red'})\n", - "node set (2, {'stroke': 'black'})" - ] - }, - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "\n", - "node set (2, {'stroke': 'black', 'fill': 'gold'})\n", - "node set (3, {'stroke': 'black'})" - ] - }, - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "\n", - "node set (3, {'stroke': 'black', 'fill': 'green'})\n", - "adj set (1, {2: {'distance': 200, 'stroke': 'lime'}, 3: {'stroke': 'lime'}, 'goodbye': {'stroke': 'lime'}})" - ] - }, - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "\n", - "adj set (1, {2: {'distance': 200, 'stroke': '#aaa'}, 3: {'stroke': 'lime'}, 'goodbye': {'stroke': 'lime'}})\n", - "adj set (1, {2: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px'}, 3: {'stroke': 'lime'}, 'goodbye': {'stroke': 'lime'}})\n", - "adj set (1, {2: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}, 3: {'stroke': 'lime'}, 'goodbye': {'stroke': 'lime'}})\n", - "adj set (1, {2: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}, 3: {'stroke': 'lime'}, 'goodbye': {'stroke': 'lime'}})\n", - "adj set (2, {1: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}})\n", - "adj set (1, {2: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}, 3: {'distance': 200, 'stroke': 'lime'}, 'goodbye': {'stroke': 'lime'}})\n", - "adj set (1, {2: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}, 3: {'distance': 200, 'stroke': '#aaa'}, 'goodbye': {'stroke': 'lime'}})\n", - "adj set (1, {2: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}, 3: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px'}, 'goodbye': {'stroke': 'lime'}})\n", - "adj set (1, {2: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}, 3: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}, 'goodbye': {'stroke': 'lime'}})\n", - "adj set (1, {2: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}, 3: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}, 'goodbye': {'stroke': 'lime'}})\n", - "adj set (3, {1: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}})\n", - "adj set (2, {1: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}, 3: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}})\n", - "adj set (3, {1: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}, 2: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}})\n", - "adj set (1, {2: {'distance': 20, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}, 3: {'distance': 200, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}, 'goodbye': {'stroke': 'lime'}})" - ] - }, - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "\n", - "adj set (1, {2: {'distance': 20, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}, 3: {'distance': 20, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}, 'goodbye': {'stroke': 'lime'}})" - ] - }, - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "\n", - "adj set (2, {1: {'distance': 20, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}, 3: {'distance': 20, 'stroke': '#aaa', 'strokewidth': '1px', 'strength': 0.5}})" - ] - }, - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "\n", - "node set (1, {'stroke': 'black', 'r': 16, 'fill': 'red'})" - ] - }, - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "\n", - "node set (1, {'stroke': 'black', 'r': 8, 'fill': 'red'})" - ] - }, - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "\n", - "node set (2, {'stroke': 'black', 'r': 16, 'fill': 'gold'})\n", - "node set (2, {'stroke': 'black', 'r': 8, 'fill': 'gold'})" - ] - }, - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "\n", - "node set (3, {'stroke': 'black', 'r': 16, 'fill': 'green'})\n", - "node set (3, {'stroke': 'black', 'r': 8, 'fill': 'green'})" - ] - }, - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "\n", - "node set (1, {'stroke': 'black', 'r': 8, 'fill': 'purple'})\n", - "node set (1, {'stroke': 'black', 'r': 8, 'fill': 'red'})" - ] - }, - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "\n", - "node set (2, {'stroke': 'black', 'r': 8, 'fill': 'purple'})\n", - "node set (2, {'stroke': 'black', 'r': 8, 'fill': 'gold'})" - ] - }, - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "\n", - "node set (3, {'stroke': 'black', 'r': 8, 'fill': 'purple'})\n", - "node set (3, {'stroke': 'black', 'r': 8, 'fill': 'green'})" - ] - }, - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "\n", - "node del 1" - ] - }, - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "\n", - "node del 2\n", - "node del 3\n", - "node del hello\n", - "node del goodbye\n" - ] - } - ], - "prompt_number": 12 - }, - { - "cell_type": "heading", - "level": 2, - "metadata": {}, - "source": [ - "Prime Factor Finder" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Find the prime numbers inside a large integer" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "def is_int(number):\n", - " return int(number) == number\n", - "\n", - "def factor_int(number):\n", - " return [i + 1 for i in range(number) if is_int(number / (float(i) + 1.0))] " - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 13 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "import time\n", - "BACKGROUND = '#F7EBD5'\n", - "PARENT_COLOR = '#66635D'\n", - "FACTOR_COLOR = '#6CC5C1'\n", - "EDGE_COLOR = '#000000'\n", - "PRIME_COLOR = '#E54140'\n", - "\n", - "existing_graphs = []\n", - "\n", - "def add_unique_node(graph, value, **kwargs):\n", - " index = len(graph.node)\n", - " graph.add_node(index, charge=-50, strokewidth=0, value=value, **kwargs)\n", - " return index\n", - "\n", - "def plot_primes(graph, number, parent, start_number, delay=0.0):\n", - " if delay > 0.0:\n", - " time.sleep(delay)\n", - " \n", - " factors = factor_int(number)\n", - " if len(factors) > 2:\n", - " for factor in factors:\n", - " if factor != number:\n", - " factor_size = max(float(factor) / start_number * 30.0,3.0)\n", - " parent_factor_size = max(float(number) / start_number * 30.0,3.0)\n", - " index = add_unique_node(graph, number, fill=FACTOR_COLOR, r='%.2fpx' % factor_size)\n", - " graph.add_edge(index, parent, distance=parent_factor_size+factor_size, stroke=EDGE_COLOR)\n", - " plot_primes(graph, factor, parent=index, start_number=start_number, delay=delay)\n", - " else:\n", - " # Prime, set parent color to prime color.\n", - " graph.node[parent]['fill'] = PRIME_COLOR\n", - "\n", - "def graph_primes(number, delay):\n", - " if len(existing_graphs) > 0:\n", - " for graph in existing_graphs:\n", - " graph.close()\n", - " del existing_graphs[:]\n", - " \n", - " floating_container = widgets.ContainerWidget(default_view_name='ModalView')\n", - " floating_container.description = \"Factors of %d\" % number\n", - " floating_container.button_text = str(number)\n", - " floating_container.set_css({\n", - " 'width': '620px',\n", - " 'height': '450px'}, selector='modal')\n", - " \n", - " graph = EventfulGraph()\n", - " d3 = ForceDirectedGraphWidget(graph, parent=floating_container)\n", - " floating_container.set_css('background', BACKGROUND)\n", - " d3.width = 600\n", - " d3.height = 400\n", - " display(floating_container)\n", - " existing_graphs.append(floating_container)\n", - " \n", - " index = add_unique_node(graph, number, fill=PARENT_COLOR, r='30px')\n", - " plot_primes(graph, number=number, parent=index, start_number=number, delay=delay)" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 14 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "box = widgets.ContainerWidget()\n", - "box.vbox()\n", - "box.align_center()\n", - "box.pack_center()\n", - "header = widgets.StringWidget(parent=box, default_view_name=\"LabelView\", value=\"

Number Factorizer


\")\n", - "subbox = widgets.ContainerWidget(parent=box)\n", - "subbox.hbox()\n", - "subbox.align_center()\n", - "subbox.pack_center()\n", - "number = widgets.IntWidget(value=100, parent=subbox)\n", - "button = widgets.ButtonWidget(description=\"Calculate\", parent=subbox)\n", - "speed = widgets.FloatRangeWidget(parent=box, min=0.0, max=0.5, value=0.4, step=0.01)\n", - "display(box)\n", - "box.add_class('well well-small')\n", - "\n", - "def handle_caclulate():\n", - " graph_primes(number.value, 0.5-speed.value)\n", - "button.on_click(handle_caclulate)\n" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "isinstance() arg 2 must be a class, type, or tuple of classes and types", - "output_type": "pyerr", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0mspeed\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mwidgets\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mFloatRangeWidget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparent\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mbox\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmin\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0.0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmax\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0.5\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0.4\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstep\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0.01\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0mdisplay\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbox\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 14\u001b[0;31m \u001b[0mbox\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_class\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'well well-small'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 15\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mhandle_caclulate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/Users/grout/projects/ipython-upstream/IPython/html/widgets/widget.pyc\u001b[0m in \u001b[0;36madd_class\u001b[0;34m(self, class_names, selector)\u001b[0m\n\u001b[1;32m 392\u001b[0m \"\"\"\n\u001b[1;32m 393\u001b[0m \u001b[0mclass_list\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mclass_names\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 394\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlist\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mclass_list\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 395\u001b[0m \u001b[0mclass_list\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m' '\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mclass_list\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 396\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mTypeError\u001b[0m: isinstance() arg 2 must be a class, type, or tuple of classes and types" - ] - } - ], - "prompt_number": 15 - }, - { - "cell_type": "heading", - "level": 2, - "metadata": {}, - "source": [ - "Twitter Tweet Watcher" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This example requires the Python \"twitter\" library to be installed (https://github.com/sixohsix/twitter). You can install Python twitter by running `sudo pip install twitter` or `sudo easy_install twitter` from the commandline." - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "from twitter import *\n", - "import time, datetime\n", - "import math\n", - "\n", - "twitter_timestamp_format = \"%a %b %d %X +0000 %Y\"" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "ename": "ImportError", - "evalue": "No module named twitter", - "output_type": "pyerr", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mImportError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0mtwitter\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdatetime\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mmath\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mtwitter_timestamp_format\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"%a %b %d %X +0000 %Y\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mImportError\u001b[0m: No module named twitter" - ] - } - ], - "prompt_number": 16 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "# Sign on to twitter.\n", - "auth = OAuth(\n", - " consumer_key='iQvYfTfuD86fgVWGjPY0UA',\n", - " consumer_secret='C3jjP6vzYzTYoHV4s5NYPGuRkpT5SulKRKTkRmYg',\n", - " token='2218195843-cOPQa0D1Yk3JbvjvsCa0tIYzBOEWxINekmGcEql',\n", - " token_secret='3BFncT1zAvJRN6rj8haCxveZVLZWZ23QeulxzByXWlfoO'\n", - ")\n", - "twitter = Twitter(auth = auth)\n", - "twitter_stream = TwitterStream(auth = auth, block = False)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'OAuth' is not defined", - "output_type": "pyerr", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Sign on to twitter.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m auth = OAuth(\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mconsumer_key\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'iQvYfTfuD86fgVWGjPY0UA'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mconsumer_secret\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'C3jjP6vzYzTYoHV4s5NYPGuRkpT5SulKRKTkRmYg'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mtoken\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'2218195843-cOPQa0D1Yk3JbvjvsCa0tIYzBOEWxINekmGcEql'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mNameError\u001b[0m: name 'OAuth' is not defined" - ] - } - ], - "prompt_number": 17 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "widget_container = widgets.ContainerWidget()\n", - "widget_container.hbox()\n", - "floating_container = widgets.ContainerWidget(parent=widget_container, default_view_name='ModalView')\n", - "floating_container.description = \"Dynamic D3 rendering of a NetworkX graph\"\n", - "floating_container.button_text = \"Render Window\"\n", - "floating_container.set_css({\n", - " 'width': '620px',\n", - " 'height': '450px'}, selector='modal')\n", - "\n", - "graph = EventfulGraph()\n", - "d3 = ForceDirectedGraphWidget(graph, parent=floating_container)\n", - "d3.width = 600\n", - "d3.height = 400\n", - "\n", - "stop_button = widgets.ButtonWidget(parent=widget_container, description=\"Stop\")\n", - "stop_button.set_css('margin-left', '5px')\n", - " \n", - "# Only listen to tweets while they are available and the user\n", - "# doesn't want to stop.\n", - "stop_listening = [False]\n", - "def handle_stop():\n", - " stop_listening[0] = True\n", - " print(\"Service stopped\")\n", - "stop_button.on_click(handle_stop)\n", - "\n", - "def watch_tweets(screen_name=None):\n", - " display(widget_container)\n", - " graph.node.clear()\n", - " graph.adj.clear()\n", - " start_timestamp = None\n", - " stop_button.add_class('btn-danger')\n", - " \n", - " # Get Barack's tweets\n", - " tweets = twitter.statuses.user_timeline(screen_name=screen_name)\n", - " user_id = twitter.users.lookup(screen_name=screen_name)[0]['id']\n", - " \n", - " # Determine the maximum number of retweets.\n", - " max_retweets = 0.0\n", - " for tweet in tweets:\n", - " max_retweets = float(max(tweet['retweet_count'], max_retweets))\n", - " \n", - " \n", - " def plot_tweet(tweet, parent=None, elapsed_seconds=1.0, color=\"gold\"):\n", - " new_id = tweet['id']\n", - " graph.add_node(\n", - " new_id, \n", - " r=max(float(tweet['retweet_count']) / max_retweets * 30.0, 3.0),\n", - " charge=-60,\n", - " fill = color,\n", - " )\n", - " \n", - " if parent is not None:\n", - " parent_radius = max(float(parent['retweet_count']) / max_retweets * 30.0, 3.0)\n", - " graph.node[parent['id']]['r'] = parent_radius\n", - " \n", - " graph.add_edge(new_id, parent['id'], distance=math.log(elapsed_seconds) * 9.0 + parent_radius)\n", - " graph.node[new_id]['fill'] = 'red'\n", - " \n", - " \n", - " # Plot each tweet.\n", - " for tweet in tweets:\n", - " plot_tweet(tweet)\n", - " \n", - " kernel=get_ipython().kernel\n", - " iterator = twitter_stream.statuses.filter(follow=user_id)\n", - " \n", - " while not stop_listening[0]:\n", - " kernel.do_one_iteration()\n", - " \n", - " for tweet in iterator:\n", - " kernel.do_one_iteration()\n", - " if stop_listening[0] or tweet is None:\n", - " break\n", - " else:\n", - " if 'retweeted_status' in tweet:\n", - " original_tweet = tweet['retweeted_status']\n", - " if original_tweet['id'] in graph.node:\n", - " tweet_timestamp = datetime.datetime.strptime(tweet['created_at'], twitter_timestamp_format) \n", - " if start_timestamp is None:\n", - " start_timestamp = tweet_timestamp\n", - " elapsed_seconds = max((tweet_timestamp - start_timestamp).total_seconds(),1.0)\n", - " \n", - " plot_tweet(tweet, parent=original_tweet, elapsed_seconds=elapsed_seconds)\n", - " elif 'id' in tweet:\n", - " plot_tweet(tweet, color='lime')\n" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "ename": "KeyError", - "evalue": "'modal'", - "output_type": "pyerr", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 6\u001b[0m floating_container.set_css({\n\u001b[1;32m 7\u001b[0m \u001b[0;34m'width'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'620px'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m 'height': '450px'}, selector='modal')\n\u001b[0m\u001b[1;32m 9\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0mgraph\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mEventfulGraph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/Users/grout/projects/ipython-upstream/IPython/html/widgets/widget.pyc\u001b[0m in \u001b[0;36mset_css\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 355\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdict\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 356\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32min\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 357\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_css\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mselector\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mvalue\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_css\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mselector\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 358\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_css\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mselector\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 359\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msend_state\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'_css'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mKeyError\u001b[0m: 'modal'" - ] - } - ], - "prompt_number": 18 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "watch_tweets(screen_name=\"justinbieber\")" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'watch_tweets' is not defined", - "output_type": "pyerr", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mwatch_tweets\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mscreen_name\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"justinbieber\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mNameError\u001b[0m: name 'watch_tweets' is not defined" - ] - } - ], - "prompt_number": 19 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 19 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [], - "language": "python", - "metadata": {}, - "outputs": [] - } - ], - "metadata": {} - } - ] -} \ No newline at end of file diff --git a/examples/widgets/Widget Tester.ipynb b/examples/widgets/Widget Tester.ipynb deleted file mode 100644 index 2aecf54..0000000 --- a/examples/widgets/Widget Tester.ipynb +++ /dev/null @@ -1,279 +0,0 @@ -{ - "metadata": { - "name": "" - }, - "nbformat": 3, - "nbformat_minor": 0, - "worksheets": [ - { - "cells": [ - { - "cell_type": "code", - "collapsed": false, - "input": [ - "from IPython.html import widgets\n", - "from IPython.display import display" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 1 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This notebook shows how widgets can be used to manipulate the properties of other widgets." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To list the properties of a widget and allow the user to modify them, a function that keeps widgets in sync with traits is required. This function will syncronize a traitlet of one widget with a traitlet of another widget. The method also supports one way syncronization of types that have string representations with string traits." - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "def sync_widgets_properties(widget_a, property_a, widget_b, property_b, str_rep=False):\n", - " def set_property_a(name, old, new):\n", - " if old != new:\n", - " if str_rep:\n", - " setattr(widget_a, property_a, str(new))\n", - " else:\n", - " setattr(widget_a, property_a, new)\n", - " def set_property_b(name, old, new):\n", - " if old != new and not str_rep:\n", - " setattr(widget_b, property_b, new)\n", - " widget_a.on_trait_change(set_property_b, property_a)\n", - " widget_b.on_trait_change(set_property_a, property_b)\n", - " if str_rep:\n", - " setattr(widget_a, property_a, str(getattr(widget_b, property_b)))\n", - " else:\n", - " setattr(widget_a, property_a, getattr(widget_b, property_b))\n", - " \n", - " return widget_a" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 2 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This function will create a best match widget to represent a traitlet of another widget. The function will then bind the two widgets using the `sync_widget_properties` method above." - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "def create_hooked_widget(control, key):\n", - " property_type = type(getattr(control, key))\n", - " \n", - " if key == \"orientation\":\n", - " return sync_widgets_properties(widgets.SelectionWidget(values=['vertical', 'horizontal'], default_view_name='ToggleButtonsView'), 'value', control, key)\n", - " elif property_type is int:\n", - " return sync_widgets_properties(widgets.IntWidget(), 'value', control, key)\n", - " elif property_type is float:\n", - " return sync_widgets_properties(widgets.FloatWidget(), 'value', control, key)\n", - " elif property_type is bool:\n", - " return sync_widgets_properties(widgets.BoolWidget(), 'value', control, key)\n", - " elif property_type is str or property_type is unicode:\n", - " return sync_widgets_properties(widgets.StringWidget(), 'value', control, key)\n", - " else:\n", - " return sync_widgets_properties(widgets.StringWidget(disabled=True), 'value', control, key, str_rep=True)\n", - " " - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 3 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This function creates a modal that allows the user to read the doc string associated with a callable. The user can then invoke the callbable from the same modal." - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "modals = {}\n", - "def get_method_modal(control, method_name, parent=None):\n", - " if not method_name in dir(control):\n", - " return None\n", - " if not control in modals:\n", - " modals[control] = {}\n", - " if not method_name in modals[control]:\n", - " new_modal = widgets.ContainerWidget(default_view_name=\"ModalView\")\n", - " new_modal.description=\"Invoke \" + method_name\n", - " new_modal.button_text = method_name + \"(...)\"\n", - " \n", - " doc_str = 'No doc string'\n", - " try:\n", - " doc_str = '
' + getattr(control, method_name).__doc__ + '
'\n", - " except:\n", - " pass\n", - " \n", - " doc_label = widgets.StringWidget(parent=new_modal,default_view_name='HTMLView', value=doc_str)\n", - " doc_label.set_css('color', 'blue')\n", - " exec_box = widgets.ContainerWidget(parent=new_modal)\n", - " exec_box.hbox()\n", - " exec_box.pack_center()\n", - " exec_box.align_center()\n", - " open_label = widgets.StringWidget(parent=exec_box,default_view_name='HTMLView', value=method_name+'(  ')\n", - " exec_str = widgets.StringWidget(parent=exec_box)\n", - " close_label = widgets.StringWidget(parent=exec_box,default_view_name='HTMLView', value='  )')\n", - " button_row = widgets.ContainerWidget(parent=new_modal)\n", - " button_row.hbox()\n", - " button_row.pack_end()\n", - " button_box = widgets.ContainerWidget(parent=button_row)\n", - " button_box.flex0()\n", - " exec_button = widgets.ButtonWidget(parent=button_box, description=\"Execute\")\n", - " \n", - " def handle_method_exec():\n", - " my_control = control\n", - " exec \"my_control.\" + method_name.replace('\\n', '') + \"(\" + exec_str.value + \")\" in globals(), locals()\n", - " exec_button.on_click(handle_method_exec)\n", - " exec_str.on_submit(handle_method_exec)\n", - " \n", - " if parent is not None:\n", - " new_modal.parent = parent\n", - " \n", - " modals[control][method_name] = new_modal\n", - " display(new_modal)\n", - " return modals[control][method_name]" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 4 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This function renders the control panel." - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "def hook_control(control, parent=None):\n", - " explorer = widgets.ContainerWidget()\n", - " if parent is not None:\n", - " explorer.parent = parent\n", - " explorer.hbox()\n", - " \n", - " viewer = widgets.ContainerWidget(parent=explorer)\n", - " viewer.set_css({\n", - " 'background': 'white',\n", - " 'border': '1px solid #000',\n", - " 'overflow': 'hidden',\n", - " })\n", - " viewer.flex2()\n", - " \n", - " control.parent = viewer\n", - " \n", - " side = widgets.ContainerWidget(parent=explorer)\n", - " side.flex1()\n", - " \n", - " side_tab = widgets.MulticontainerWidget(parent=side)\n", - " side_tab.set_css('margin', '5px')\n", - " \n", - " properties = widgets.ContainerWidget(parent=side_tab)\n", - " methods = widgets.ContainerWidget(parent=side_tab)\n", - " side_tab.set_title(0, 'Properties')\n", - " side_tab.set_title(1, 'Methods')\n", - " \n", - " for key in sorted(control.keys):\n", - " property_control = create_hooked_widget(control, key)\n", - " property_control.parent = properties\n", - " property_control.description = key + ':'\n", - " \n", - " methods.vbox()\n", - " methods.set_css('overflow', 'hidden')\n", - " \n", - " methods_container = widgets.ContainerWidget(parent=methods)\n", - " methods_container.flex1()\n", - " methods_buttons = widgets.ContainerWidget(parent=methods)\n", - " methods_buttons.flex0()\n", - " methods_buttons.hbox()\n", - " methods_buttons.pack_end()\n", - " methods_buttons.set_css({\n", - " 'padding-top': '5px',\n", - " 'padding-right': '50px',\n", - " })\n", - " \n", - " execute_button = widgets.ButtonWidget(parent=methods_buttons, description=\"Invoke\")\n", - " \n", - " method_list = widgets.SelectionWidget(parent=methods_container, default_view_name=\"ListBoxView\")\n", - " method_list.description = \"Names:\"\n", - " method_list.set_css('height', '400px')\n", - " method_list.values = [attr_name for attr_name in dir(control) if callable(getattr(control, attr_name)) and not attr_name.startswith('_')]\n", - " \n", - " def handle_execute_method():\n", - " get_method_modal(control, method_list.value, parent=parent)\n", - " execute_button.on_click(handle_execute_method)\n", - " \n", - " display(explorer) \n", - " explorer.add_class('well')\n", - " return explorer" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 5 - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This final bit of code allows the user to select what control and view he/she wants to manipulate." - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "control_tester = widgets.ContainerWidget()\n", - "widget_names = [widget_name for widget_name in dir(widgets) if widget_name.endswith('Widget') and widget_name != \"Widget\"]\n", - "widget_selector = widgets.SelectionWidget(parent=control_tester, description=\"Widget type:\", values=widget_names)\n", - "view_name = widgets.StringWidget(parent=control_tester, description=\"View name (optional):\")\n", - "display_button_container = widgets.ContainerWidget(parent=control_tester)\n", - "display_button_container.hbox()\n", - "display_button_container.pack_end()\n", - "display_button_container.set_css(\"padding\", \"5px\")\n", - "display_button = widgets.ButtonWidget(parent=display_button_container, description=\"Display\")\n", - "display(control_tester)\n", - "\n", - "last_displayed = [None]\n", - "def handle_display():\n", - " if last_displayed[0] is not None:\n", - " last_displayed[0].close()\n", - " widget_type = getattr(widgets, widget_selector.value)\n", - " widget = widget_type()\n", - " if len(view_name.value) > 0:\n", - " widget.default_view_name = view_name.value\n", - " last_displayed[0] = hook_control(widget)\n", - "display_button.on_click(handle_display)\n", - "view_name.on_submit(handle_display)\n" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 6 - } - ], - "metadata": {} - } - ] -} \ No newline at end of file