Skip to content

Instantly share code, notes, and snippets.

@ellisonbg
Created June 17, 2014 18:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ellisonbg/0fd6d758b2fbd0185cdd to your computer and use it in GitHub Desktop.
Save ellisonbg/0fd6d758b2fbd0185cdd to your computer and use it in GitHub Desktop.
Two Dimensional Slider Widget for IPython
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": "",
"signature": "sha256:3e9e96b95a6929e837848093c3b020e319e6a0462ddc4a19f416a5e8c8fee1d8"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"2-D Slider"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This is an example of how you could make your own two-dimensional slider widget.\n",
"\n",
"Author: Tyler Murphy, Cal Poly Physics Major"
]
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Python Code"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First, the necessary libraries from IPython need to be imported. An excellent explanation of the basics is provided in parts one through five of the widgets tutorial found in ipython/examples/widgets"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from __future__ import print_function\n",
"from IPython.html import widgets\n",
"from IPython.display import display\n",
"from IPython.utils.traitlets import Unicode\n",
"from IPython.html.widgets import DOMWidget"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following code declares which variables are synced between python and javascript using a backbone model. The values given are the defaults. Note that the first line imports the variable types that are used to describe the widget."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from IPython.utils.traitlets import Unicode, Int, Float\n",
"\n",
"class TwoDimSlider(DOMWidget):\n",
" _view_name = Unicode('TwoDimSliderView', sync=True)\n",
" x = Float(0.0, sync=True)\n",
" y = Float(0.0, sync=True)\n",
" xmin = Float(0.0, sync=True)\n",
" xmax = Float(1.0, sync=True)\n",
" ymin = Float(0.0, sync=True)\n",
" ymax = Float(1.0, sync=True)\n",
" width = Int(100, sync=True)\n",
" height = Int(100, sync=True)\n",
" round_factor = Int(2, sync=True) #the number of digits after the decimal\n",
" marker_size = Int(20, sync=True) #marker diameter in pixels"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 2
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Javascript"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following cell is defined as javascript using cell magics. The '%%javascript' must be on the first line of the cell and defines the remainder of the cell to contain javascript. Comments throughout the following cell explain what different parts of the code are for."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%javascript\n",
"\n",
"require([\"widgets/js/widget\"], function(WidgetManager) {\n",
" \n",
" //The 'TwoDimSliderView' below is the name of a particular view associated with this widget.\n",
" //A widget can have more than one view, and each one would be defined in the same way, by\n",
" //extending the DOMWidgetView. This widget happens to have just one view. The view displayed\n",
" //is controlled just like any other parameter, using the _view_name key. \n",
" var TwoDimSliderView = IPython.DOMWidgetView.extend({\n",
" \n",
" //The view needs to have a function called 'render' which builds the slider.\n",
" render: function() {\n",
" \n",
" // The parameters for the widget are retrieved using 'this.model.get('key_name')'\n",
" // Get the bounds on the slider range\n",
" var xmin = this.model.get('xmin');\n",
" var ymin = this.model.get('ymin');\n",
" var xmax = this.model.get('xmax');\n",
" var ymax = this.model.get('ymax');\n",
" \n",
" // In general, don't store any state variables. Get them each time you need them so\n",
" // they're not out of date. Within a function, though, it's okay to assign to a \n",
" // variable and reuse it rather than getting it several times. Getting it each time\n",
" // is okay, too, since it's very fast.\n",
" \n",
" // Get the slider's size\n",
" var x_size = this.model.get('width');\n",
" var y_size = this.model.get('height');\n",
" \n",
" // Get marker size and position\n",
" var marker_size = this.model.get('marker_size');\n",
" var x = this.model.get('x');\n",
" var y = this.model.get('y');\n",
" \n",
" // Create the slider elements:\n",
" // The slider is built up piece by piece using different HTML elements appended to\n",
" // each other. Jquery and css styling is used to control the look of each piece.\n",
" \n",
" //The markerbounds define the draggable area of the marker.\n",
" this.$markerbounds = $('<div />')\n",
" .appendTo(this.$el)\n",
" .width(x_size + marker_size)\n",
" .height(y_size + marker_size)\n",
" .css({\"margin-left\": \"15px\"});\n",
" \n",
" // This box is a visual representation of the draggable area of the marker. It bounds\n",
" // the center of the marker.\n",
" this.$box = $('<div />')\n",
" .appendTo(this.$markerbounds)\n",
" .width(x_size)\n",
" .height(y_size)\n",
" .css({\"top\": marker_size / 2,\n",
" \"left\": marker_size / 2,\n",
" \"position\": \"relative\",\n",
" });\n",
" \n",
" this.$marker = $('<div />')\n",
" .appendTo(this.$box)\n",
" .width(marker_size)\n",
" .height(marker_size)\n",
" .css({\"border-radius\": 1000,\n",
" \"background-color\": \"black\",\n",
" });\n",
" \n",
" this.$coordx = $('<div class=\"coord\" />')\n",
" .appendTo(this.$el)\n",
" .css({\n",
" \"top\": 0,\n",
" \"position\": \"relative\",\n",
" \"text-align\": \"center\",\n",
" });\n",
" this.$xlabel = $('<div />')\n",
" .appendTo(this.$coordx)\n",
" .text('x:')\n",
" .css({\"display\": \"inline-block\"});\n",
" this.$xvalue = $('<div />')\n",
" .appendTo(this.$coordx)\n",
" .css({\"display\": \"inline-block\"});\n",
" \n",
" this.$coordy = $('<div class=\"coord\" />')\n",
" .appendTo(this.$el)\n",
" .css({\n",
" \"position\": \"relative\",\n",
" \"-webkit-transform\": \"rotate(-90deg)\",\n",
" \"-moz-transform\": \"rotate(-90deg)\",\n",
" \"-ms-transform\": \"rotate(-90deg)\",\n",
" \"-o-transform\": \"rotate(-90deg)\",\n",
" \"width\": y_size,\n",
" \"top\": -y_size,\n",
" \"left\": -(y_size / 2) + 5,\n",
" });\n",
" this.$ylabel = $('<div />')\n",
" .appendTo(this.$coordy)\n",
" .text('y: ')\n",
" .css({\"display\": \"inline-block\"});\n",
" this.$yvalue = $('<div />')\n",
" .appendTo(this.$coordy)\n",
" .css({\"display\": \"inline-block\"});\n",
" \n",
" // A Jquery UI function called draggable makes the marker draggable. Each time\n",
" // the position of the marker changes the display_position and save_position\n",
" // functions are called.\n",
" var that = this;\n",
" this.$marker.draggable({\n",
" containment: this.$markerbounds,\n",
" scroll: false,\n",
" drag: function() {\n",
" that.display_position();\n",
" that.save_position();\n",
" },\n",
" });\n",
" \n",
" // Now, functions are defined to handle changes in the widget values that\n",
" // necessitate a change in its appearance.\n",
" // this.model.on(\"change:key_name\", do_this()) is used to watch for changes\n",
" // in a particular key and then execute the function do_this when there's\n",
" // a change.\n",
" \n",
" //Handle slider position change:\n",
" var handle_pos_change = function() {\n",
" that.move_marker(that.model.get('x'),that.model.get('y'))\n",
" };\n",
" this.model.on(\"change:x\", handle_pos_change);\n",
" this.model.on(\"change:y\", handle_pos_change);\n",
" \n",
" //Handle slider size change:\n",
" //Width and height:\n",
" var handle_size_change = function() {\n",
" //Save the old x and y positions so that the marker can be moved and its value\n",
" //from before resizing isn't lost:\n",
" var x_old = that.model.get('x');\n",
" var y_old = that.model.get('y');\n",
" \n",
" //Change the sizing and positioning of the relevant elements:\n",
" that.$markerbounds.width(that.model.get('width') + that.model.get('marker_size'))\n",
" .height(that.model.get('height') + that.model.get('marker_size'));\n",
" that.$box.width(that.model.get('width'))\n",
" .height(that.model.get('height'))\n",
" .css({\"top\": that.model.get('marker_size') / 2,\n",
" \"left\": that.model.get('marker_size') / 2,\n",
" \"position\": \"relative\",\n",
" });\n",
" that.$coordy.css({\n",
" \"width\": that.model.get('height'),\n",
" \"top\": -that.model.get('height'),\n",
" \"left\": -(that.model.get('height') / 2) + 5,\n",
" });\n",
" that.$marker.width(that.model.get('marker_size'))\n",
" .height(that.model.get('marker_size'));\n",
" \n",
" //Move the marker to where it should be now that the size has changed.\n",
" that.move_marker(x_old, y_old);\n",
" that.get_position();\n",
" that.display_position();\n",
" };\n",
" this.model.on(\"change:width\", handle_size_change);\n",
" this.model.on(\"change:height\", handle_size_change);\n",
" this.model.on(\"change:marker_size\", handle_size_change);\n",
" \n",
" //Handle changes in the range of the slider:\n",
" var handle_range_change = function() {\n",
" that.get_position();\n",
" that.save_position();\n",
" that.display_position();\n",
" };\n",
" this.model.on(\"change:xmin\", handle_range_change);\n",
" this.model.on(\"change:xmax\", handle_range_change);\n",
" this.model.on(\"change:ymin\", handle_range_change);\n",
" this.model.on(\"change:ymax\", handle_range_change);\n",
" \n",
" //Move the marker to the correct starting position:\n",
" this.move_marker(x, y);\n",
" //And label the axes:\n",
" this.$xvalue.html(x.toString());\n",
" this.$yvalue.html(y.toString());\n",
" \n",
" // This line defines which element will be styled when using the set_css method\n",
" // for the widget\n",
" this.$el_to_style = this.$box;\n",
" \n",
" },\n",
" \n",
" //Other functions which do things like move the marker can also be defined.\n",
" move_marker: function(x, y) {\n",
" var y_size = this.model.get('height');\n",
" var x_size = this.model.get('width');\n",
" var marker_size = this.model.get('marker_size');\n",
" \n",
" var xmin = this.model.get('xmin');\n",
" var xmax = this.model.get('xmax');\n",
" var ymin = this.model.get('ymin');\n",
" var ymax = this.model.get('ymax');\n",
" \n",
" if (x > xmax) {\n",
" x = xmax;\n",
" } else if (x < xmin) {\n",
" x = xmin;\n",
" }\n",
" \n",
" if (y > ymax) {\n",
" y = ymax;\n",
" } else if (y < ymin) {\n",
" y = ymin;\n",
" }\n",
" \n",
" //Calculate the necessary positions:\n",
" var top = (y_size - (((y - ymin) / (ymax - ymin)) * y_size)) - (marker_size / 2);\n",
" var left = (((x - xmin) / (xmax - xmin)) * x_size) - (marker_size / 2);\n",
" \n",
" //Move the marker\n",
" this.$marker.css({\n",
" \"top\": top.toString() + \"px\",\n",
" \"left\": left.toString() + \"px\",\n",
" });\n",
" this.display_position();\n",
" },\n",
" \n",
" get_round_factor: function() {\n",
" var decimals = Math.pow(10,this.model.get('round_factor'));\n",
" return decimals;\n",
" },\n",
" \n",
" get_position: function() { \n",
" //Get values necessary to calculate position:\n",
" var round_factor = this.get_round_factor();\n",
" var xrange = [this.model.get('xmin'), this.model.get('xmax')];\n",
" var yrange = [this.model.get('ymin'), this.model.get('ymax')];\n",
" var width = this.model.get('width');\n",
" var height = this.model.get('height');\n",
" var marker_size = this.model.get('marker_size');\n",
" \n",
" //Get the slider's position on the page\n",
" var marker_pos = this.$marker.position();\n",
" var left_pos = marker_pos.left + marker_size / 2;\n",
" var top_pos = marker_pos.top + marker_size / 2;\n",
" \n",
" //Calculate position\n",
" var position = {\n",
" x: Math.round(round_factor * ((left_pos * (xrange[1] - xrange[0]) / width) + xrange[0] )) / round_factor,\n",
" y: Math.round(round_factor * (( (height - top_pos) * (yrange[1] - yrange[0]) / height) + yrange[0] )) / round_factor,\n",
" };\n",
" return position;\n",
" },\n",
" \n",
" // The save_position function uses this.model.set to update values in the\n",
" // backbone model. Call this.touch() after setting to push the values.\n",
" save_position: function() {\n",
" //Get position:\n",
" var position = this.get_position();\n",
" \n",
" //Update the x- and y-values in python:\n",
" this.model.set('x',position.x);\n",
" this.model.set('y',position.y);\n",
" this.touch();\n",
" },\n",
" \n",
" display_position: function() {\n",
" //Get position:\n",
" var position = this.get_position();\n",
" //Update the view:\n",
" this.$xvalue.html(position.x.toString());\n",
" this.$yvalue.html(position.y.toString());\n",
" },\n",
"\n",
" });\n",
" \n",
" // Register the widget view with the widget manager using the python view name first, followed\n",
" //by the name of the widget in javscript.\n",
" WidgetManager.register_widget_view('TwoDimSliderView', TwoDimSliderView);\n",
" \n",
"});"
],
"language": "python",
"metadata": {},
"outputs": [
{
"javascript": [
"\n",
"require([\"widgets/js/widget\"], function(WidgetManager) {\n",
" \n",
" //The 'TwoDimSliderView' below is the name of a particular view associated with this widget.\n",
" //A widget can have more than one view, and each one would be defined in the same way, by\n",
" //extending the DOMWidgetView. This widget happens to have just one view. The view displayed\n",
" //is controlled just like any other parameter, using the _view_name key. \n",
" var TwoDimSliderView = IPython.DOMWidgetView.extend({\n",
" \n",
" //The view needs to have a function called 'render' which builds the slider.\n",
" render: function() {\n",
" \n",
" // The parameters for the widget are retrieved using 'this.model.get('key_name')'\n",
" // Get the bounds on the slider range\n",
" var xmin = this.model.get('xmin');\n",
" var ymin = this.model.get('ymin');\n",
" var xmax = this.model.get('xmax');\n",
" var ymax = this.model.get('ymax');\n",
" \n",
" // In general, don't store any state variables. Get them each time you need them so\n",
" // they're not out of date. Within a function, though, it's okay to assign to a \n",
" // variable and reuse it rather than getting it several times. Getting it each time\n",
" // is okay, too, since it's very fast.\n",
" \n",
" // Get the slider's size\n",
" var x_size = this.model.get('width');\n",
" var y_size = this.model.get('height');\n",
" \n",
" // Get marker size and position\n",
" var marker_size = this.model.get('marker_size');\n",
" var x = this.model.get('x');\n",
" var y = this.model.get('y');\n",
" \n",
" // Create the slider elements:\n",
" // The slider is built up piece by piece using different HTML elements appended to\n",
" // each other. Jquery and css styling is used to control the look of each piece.\n",
" \n",
" //The markerbounds define the draggable area of the marker.\n",
" this.$markerbounds = $('<div />')\n",
" .appendTo(this.$el)\n",
" .width(x_size + marker_size)\n",
" .height(y_size + marker_size)\n",
" .css({\"margin-left\": \"15px\"});\n",
" \n",
" // This box is a visual representation of the draggable area of the marker. It bounds\n",
" // the center of the marker.\n",
" this.$box = $('<div />')\n",
" .appendTo(this.$markerbounds)\n",
" .width(x_size)\n",
" .height(y_size)\n",
" .css({\"top\": marker_size / 2,\n",
" \"left\": marker_size / 2,\n",
" \"position\": \"relative\",\n",
" });\n",
" \n",
" this.$marker = $('<div />')\n",
" .appendTo(this.$box)\n",
" .width(marker_size)\n",
" .height(marker_size)\n",
" .css({\"border-radius\": 1000,\n",
" \"background-color\": \"black\",\n",
" });\n",
" \n",
" this.$coordx = $('<div class=\"coord\" />')\n",
" .appendTo(this.$el)\n",
" .css({\n",
" \"top\": 0,\n",
" \"position\": \"relative\",\n",
" \"text-align\": \"center\",\n",
" });\n",
" this.$xlabel = $('<div />')\n",
" .appendTo(this.$coordx)\n",
" .text('x:')\n",
" .css({\"display\": \"inline-block\"});\n",
" this.$xvalue = $('<div />')\n",
" .appendTo(this.$coordx)\n",
" .css({\"display\": \"inline-block\"});\n",
" \n",
" this.$coordy = $('<div class=\"coord\" />')\n",
" .appendTo(this.$el)\n",
" .css({\n",
" \"position\": \"relative\",\n",
" \"-webkit-transform\": \"rotate(-90deg)\",\n",
" \"-moz-transform\": \"rotate(-90deg)\",\n",
" \"-ms-transform\": \"rotate(-90deg)\",\n",
" \"-o-transform\": \"rotate(-90deg)\",\n",
" \"width\": y_size,\n",
" \"top\": -y_size,\n",
" \"left\": -(y_size / 2) + 5,\n",
" });\n",
" this.$ylabel = $('<div />')\n",
" .appendTo(this.$coordy)\n",
" .text('y: ')\n",
" .css({\"display\": \"inline-block\"});\n",
" this.$yvalue = $('<div />')\n",
" .appendTo(this.$coordy)\n",
" .css({\"display\": \"inline-block\"});\n",
" \n",
" // A Jquery UI function called draggable makes the marker draggable. Each time\n",
" // the position of the marker changes the display_position and save_position\n",
" // functions are called.\n",
" var that = this;\n",
" this.$marker.draggable({\n",
" containment: this.$markerbounds,\n",
" scroll: false,\n",
" drag: function() {\n",
" that.display_position();\n",
" that.save_position();\n",
" },\n",
" });\n",
" \n",
" // Now, functions are defined to handle changes in the widget values that\n",
" // necessitate a change in its appearance.\n",
" // this.model.on(\"change:key_name\", do_this()) is used to watch for changes\n",
" // in a particular key and then execute the function do_this when there's\n",
" // a change.\n",
" \n",
" //Handle slider position change:\n",
" var handle_pos_change = function() {\n",
" that.move_marker(that.model.get('x'),that.model.get('y'))\n",
" };\n",
" this.model.on(\"change:x\", handle_pos_change);\n",
" this.model.on(\"change:y\", handle_pos_change);\n",
" \n",
" //Handle slider size change:\n",
" //Width and height:\n",
" var handle_size_change = function() {\n",
" //Save the old x and y positions so that the marker can be moved and its value\n",
" //from before resizing isn't lost:\n",
" var x_old = that.model.get('x');\n",
" var y_old = that.model.get('y');\n",
" \n",
" //Change the sizing and positioning of the relevant elements:\n",
" that.$markerbounds.width(that.model.get('width') + that.model.get('marker_size'))\n",
" .height(that.model.get('height') + that.model.get('marker_size'));\n",
" that.$box.width(that.model.get('width'))\n",
" .height(that.model.get('height'))\n",
" .css({\"top\": that.model.get('marker_size') / 2,\n",
" \"left\": that.model.get('marker_size') / 2,\n",
" \"position\": \"relative\",\n",
" });\n",
" that.$coordy.css({\n",
" \"width\": that.model.get('height'),\n",
" \"top\": -that.model.get('height'),\n",
" \"left\": -(that.model.get('height') / 2) + 5,\n",
" });\n",
" that.$marker.width(that.model.get('marker_size'))\n",
" .height(that.model.get('marker_size'));\n",
" \n",
" //Move the marker to where it should be now that the size has changed.\n",
" that.move_marker(x_old, y_old);\n",
" that.get_position();\n",
" that.display_position();\n",
" };\n",
" this.model.on(\"change:width\", handle_size_change);\n",
" this.model.on(\"change:height\", handle_size_change);\n",
" this.model.on(\"change:marker_size\", handle_size_change);\n",
" \n",
" //Handle changes in the range of the slider:\n",
" var handle_range_change = function() {\n",
" that.get_position();\n",
" that.save_position();\n",
" that.display_position();\n",
" };\n",
" this.model.on(\"change:xmin\", handle_range_change);\n",
" this.model.on(\"change:xmax\", handle_range_change);\n",
" this.model.on(\"change:ymin\", handle_range_change);\n",
" this.model.on(\"change:ymax\", handle_range_change);\n",
" \n",
" //Move the marker to the correct starting position:\n",
" this.move_marker(x, y);\n",
" //And label the axes:\n",
" this.$xvalue.html(x.toString());\n",
" this.$yvalue.html(y.toString());\n",
" \n",
" // This line defines which element will be styled when using the set_css method\n",
" // for the widget\n",
" this.$el_to_style = this.$box;\n",
" \n",
" },\n",
" \n",
" //Other functions which do things like move the marker can also be defined.\n",
" move_marker: function(x, y) {\n",
" var y_size = this.model.get('height');\n",
" var x_size = this.model.get('width');\n",
" var marker_size = this.model.get('marker_size');\n",
" \n",
" var xmin = this.model.get('xmin');\n",
" var xmax = this.model.get('xmax');\n",
" var ymin = this.model.get('ymin');\n",
" var ymax = this.model.get('ymax');\n",
" \n",
" if (x > xmax) {\n",
" x = xmax;\n",
" } else if (x < xmin) {\n",
" x = xmin;\n",
" }\n",
" \n",
" if (y > ymax) {\n",
" y = ymax;\n",
" } else if (y < ymin) {\n",
" y = ymin;\n",
" }\n",
" \n",
" //Calculate the necessary positions:\n",
" var top = (y_size - (((y - ymin) / (ymax - ymin)) * y_size)) - (marker_size / 2);\n",
" var left = (((x - xmin) / (xmax - xmin)) * x_size) - (marker_size / 2);\n",
" \n",
" //Move the marker\n",
" this.$marker.css({\n",
" \"top\": top.toString() + \"px\",\n",
" \"left\": left.toString() + \"px\",\n",
" });\n",
" this.display_position();\n",
" },\n",
" \n",
" get_round_factor: function() {\n",
" var decimals = Math.pow(10,this.model.get('round_factor'));\n",
" return decimals;\n",
" },\n",
" \n",
" get_position: function() { \n",
" //Get values necessary to calculate position:\n",
" var round_factor = this.get_round_factor();\n",
" var xrange = [this.model.get('xmin'), this.model.get('xmax')];\n",
" var yrange = [this.model.get('ymin'), this.model.get('ymax')];\n",
" var width = this.model.get('width');\n",
" var height = this.model.get('height');\n",
" var marker_size = this.model.get('marker_size');\n",
" \n",
" //Get the slider's position on the page\n",
" var marker_pos = this.$marker.position();\n",
" var left_pos = marker_pos.left + marker_size / 2;\n",
" var top_pos = marker_pos.top + marker_size / 2;\n",
" \n",
" //Calculate position\n",
" var position = {\n",
" x: Math.round(round_factor * ((left_pos * (xrange[1] - xrange[0]) / width) + xrange[0] )) / round_factor,\n",
" y: Math.round(round_factor * (( (height - top_pos) * (yrange[1] - yrange[0]) / height) + yrange[0] )) / round_factor,\n",
" };\n",
" return position;\n",
" },\n",
" \n",
" // The save_position function uses this.model.set to update values in the\n",
" // backbone model. Call this.touch() after setting to push the values.\n",
" save_position: function() {\n",
" //Get position:\n",
" var position = this.get_position();\n",
" \n",
" //Update the x- and y-values in python:\n",
" this.model.set('x',position.x);\n",
" this.model.set('y',position.y);\n",
" this.touch();\n",
" },\n",
" \n",
" display_position: function() {\n",
" //Get position:\n",
" var position = this.get_position();\n",
" //Update the view:\n",
" this.$xvalue.html(position.x.toString());\n",
" this.$yvalue.html(position.y.toString());\n",
" },\n",
"\n",
" });\n",
" \n",
" // Register the widget view with the widget manager using the python view name first, followed\n",
" //by the name of the widget in javscript.\n",
" WidgetManager.register_widget_view('TwoDimSliderView', TwoDimSliderView);\n",
" \n",
"});"
],
"metadata": {},
"output_type": "display_data",
"text": [
"<IPython.core.display.Javascript object>"
]
}
],
"prompt_number": 3
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Widget Usage"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Use the following line to create an instance of the widget with the name 'w'."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"w = TwoDimSlider()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then, to display the widget, either call 'w', or just use the display command. The set_css method can be used to set css properties for whichever HTML element is assigned to this.$el_to_style in javascript. Note that the defaults defined in python were used to render the widget."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"display(w)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 5
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"w.set_css(\"background\", \"purple\")"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 6
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The position of the slider, the marker size, and the size of the slider can also be changed:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"w.x = 0.5\n",
"w.y = 0.75"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 7
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"w.marker_size = 30"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 8
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"w.width = 150\n",
"w.height = 150"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 9
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The range of the slider can be changed. Changing the range doesn't change the x- and y-values, so the position of the marker in the bounding box changes. The number of digits after the decimal the x- and y-values are rounded to is controlled using the round_factor parameter. Negative values for round_factor allow rounding to ones, tens, hundreds, etc."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"w.xmin = -3\n",
"w.ymax = 3\n",
"w.round_factor = 1"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 10
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The slider can be displayed again. Since it's just a visual representation of the data in the backbone model, every instance of the slider on the page moves together."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"display(w)\n",
"display(w)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 11
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The slider can also be linked to other widgets. For example, the x-value of this slider is linked to a one-dimensional slider:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from IPython.utils.traitlets import link\n",
"x = widgets.FloatSliderWidget(min=-3.0, max=1.0, step=0.1)\n",
"link((w, 'x'), (x, 'value'))\n",
"display(x)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 12
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"All of the keys for the widget can be viewed using the following command."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"w.keys"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 9,
"text": [
"['_view_name',\n",
" 'ymax',\n",
" 'msg_throttle',\n",
" 'width',\n",
" 'marker_size',\n",
" '_css',\n",
" 'height',\n",
" 'visible',\n",
" 'xmax',\n",
" 'xmin',\n",
" 'x',\n",
" 'ymin',\n",
" 'y',\n",
" 'round_factor']"
]
}
],
"prompt_number": 9
},
{
"cell_type": "heading",
"level": 3,
"metadata": {},
"source": [
"Acknowledgments"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Thanks to Brian Granger and Jonathan Frederic for all the help they gave me along the way."
]
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment