Skip to content

Instantly share code, notes, and snippets.

Created April 4, 2014 14:36
Show Gist options
  • Save anonymous/9975962 to your computer and use it in GitHub Desktop.
Save anonymous/9975962 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": "",
"signature": "sha256:5ebe6f1a163ef6aa50c86fa6b32eb5d00c898648ffd9a2eb22a0bacfefa101c5"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# d3.js in IPython 2.0\n",
"\n",
"With the addition of [interactive widgets](https://github.com/ipython/ipython/wiki/IPEP-23%3A-Backbone.js-Widgets), an IPython notebook is now:\n",
"\n",
"- a multi-language aware text editor, thanks to [CodeMirror](http://codemirror.net/)\n",
" - This notebook uses Markdown, Javascript and, obviously, Python.\n",
"- a static web page\n",
" - what you might be looking at right now\n",
"- a rapid prototyping environment\n",
" - forget about models, views and controllers: just think about data\n",
"- a presentation, thanks to [reveal.js](http://lab.hakim.se/reveal-js/#/)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This being I_Python_, we do first need a Python class."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from IPython.display import display\n",
"from IPython.html import widgets as W\n",
"from IPython.utils import traitlets as T\n",
"\n",
"class CirclesWidget(W.DOMWidget):\n",
" _view_name = T.Unicode('CirclesView', sync=True)\n",
" radii = T.List(sync=True)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Make d3 available to `require.js` with a single line."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%javascript\n",
"require.config({paths: {d3: \"//d3js.org/d3.v3.min\"}});"
],
"language": "python",
"metadata": {},
"outputs": [
{
"javascript": [
"require.config({paths: {d3: \"//d3js.org/d3.v3.min\"}});"
],
"metadata": {},
"output_type": "display_data",
"text": [
"<IPython.core.display.Javascript at 0x35231b0>"
]
}
],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Create an `IPython.DOMWidgetView` subclass (which is itself a subclass of `Backbone.View`)."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%javascript\n",
"require([\"widgets/js/widget\", \"d3\"], function(WidgetManager, d3){\n",
" var CirclesView = IPython.DOMWidgetView.extend({\n",
" render: function(){\n",
" this.svg = d3.select(this.el).append(\"svg\")\n",
" .attr({\n",
" width: 500,\n",
" height: 100\n",
" });\n",
"\n",
" this.update();\n",
" },\n",
" update: function(){\n",
" var radii = this.model.get(\"radii\"),\n",
" circle = this.svg.selectAll(\"circle\")\n",
" .data(radii);\n",
"\n",
" circle.enter().append(\"circle\")\n",
" .style({fill: \"red\", opacity: .5})\n",
" .attr({cy: 50})\n",
" .on(\"click\", this.click.bind(this));\n",
"\n",
" circle.transition()\n",
" .attr({\n",
" cx: function(d, i){ return (i+1) * 50; },\n",
" r: function(d){ return d * 10; }\n",
" });\n",
"\n",
" circle.exit()\n",
" .transition()\n",
" .style({fill: \"black\", opacity: 0})\n",
" .remove();\n",
" },\n",
" click: function(d, i){\n",
" var new_radii = this.model.get(\"radii\").slice();\n",
" new_radii[i] += 1;\n",
" this.model.set(\"radii\", new_radii);\n",
" this.touch();\n",
" }\n",
" });\n",
" WidgetManager.register_widget_view(\"CirclesView\", CirclesView);\n",
"});"
],
"language": "python",
"metadata": {},
"outputs": [
{
"javascript": [
"require([\"widgets/js/widget\", \"d3\"], function(WidgetManager, d3){\n",
" var CirclesView = IPython.DOMWidgetView.extend({\n",
" render: function(){\n",
" this.svg = d3.select(this.el).append(\"svg\")\n",
" .attr({\n",
" width: 500,\n",
" height: 100\n",
" });\n",
"\n",
" this.update();\n",
" },\n",
" update: function(){\n",
" var radii = this.model.get(\"radii\"),\n",
" circle = this.svg.selectAll(\"circle\")\n",
" .data(radii);\n",
"\n",
" circle.enter().append(\"circle\")\n",
" .style({fill: \"red\", opacity: .5})\n",
" .attr({cy: 50})\n",
" .on(\"click\", this.click.bind(this));\n",
"\n",
" circle.transition()\n",
" .attr({\n",
" cx: function(d, i){ return (i+1) * 50; },\n",
" r: function(d){ return d * 10; }\n",
" });\n",
"\n",
" circle.exit()\n",
" .transition()\n",
" .style({fill: \"black\", opacity: 0})\n",
" .remove();\n",
" },\n",
" click: function(d, i){\n",
" var new_radii = this.model.get(\"radii\").slice();\n",
" new_radii[i] += 1;\n",
" this.model.set(\"radii\", new_radii);\n",
" this.touch();\n",
" }\n",
" });\n",
" WidgetManager.register_widget_view(\"CirclesView\", CirclesView);\n",
"});"
],
"metadata": {},
"output_type": "display_data",
"text": [
"<IPython.core.display.Javascript at 0x356c9f0>"
]
}
],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Create an instance of the new class, and ask IPython to display it."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"circles = CirclesWidget(radii=[1,2,3])\n",
"display(circles)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Change the values, and see it update"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"circles.radii = [3,2,1]"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 5
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Or make some changes over time."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import time\n",
"import random\n",
"for i in range(10):\n",
" time.sleep(1)\n",
" circles.radii = random.sample(range(10), random.randint(0, 10))"
],
"language": "python",
"metadata": {},
"outputs": []
}
],
"metadata": {}
}
]
}
@lucienboillod
Copy link

Nice example !
Do you think it's possible to give an array of object as argument, instead an array of int ( like a = CirclesWidget(radii=[{id: 1, reflexive: false}) ), because I would like to mix backbone and D3 but my data are array of objects

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment