Create a _repr_javascript_ method that creates and shows a HTML5 canvas with a figure

142 views
Skip to first unread message

Björn Johansson

unread,
Jan 15, 2017, 11:28:32 AM1/15/17
to Project Jupyter
Hi, I would like to add a javascript representation to the class below. I would like to have a circle drawn on a HTML5 canvas. Is this even possible? The code below does not work and I do not know very much javascript. I would be grateful for help. The code below executes, but nothing is drawn in the cell. I have looked at the ipywidgets, but it is not clear to me how to modify the code below.

class MyCircle(object):

    def __init__(self, center=(0.0,0.0), radius=1.0, color='blue'):
        self.center = center
        self.radius = radius
        self.color = color

    def _repr_html_(self):
        return "&#x25CB; (<b>html</b>)"

    def _repr_svg_(self):
        return """<svg width="100px" height="100px">
           <circle cx="50" cy="50" r="20" stroke="black" stroke-width="1" fill="blue"/>
        </svg>"""
    
    def _repr_latex_(self):
        return r"$\bigcirc \LaTeX$"

    def _repr_javascript_(self):            
        s=(    'var canvas = document.createElement("canvas");'    
               'canvas.height= 400;'
               'canvas.width = 400;'
               'var context = canvas.getContext("2d");'
               'document.body.appendChild(canvas);')
        return s

Björn Johansson

unread,
Jan 18, 2017, 11:31:08 AM1/18/17
to Project Jupyter
I figured out a crude way to do this. See this notebook.
The _repr_javascript method now draws a circle.

Steven Silvester

unread,
Jan 19, 2017, 6:38:32 AM1/19/17
to Project Jupyter
Hi Björn,

You can combine the HTML and JavaScript into `_repr_html_`:


```
class MyCircle(object):

    def __init__(self, center=(0.0,0.0), radius=1.0, color='blue'):
        self.center = center
        self.radius = radius
        self.color = color

    def _repr_html_(self):
        return '''
        <canvas id='mycircle'/>
        <script>
        var c = document.getElementById("mycircle");
        var ctx = c.getContext("2d");
        ctx.beginPath();
        ctx.arc(100, 75, {}, 0, 2 * Math.PI);
        ctx.stroke();
        </script>'''.format(self.radius)

    def _repr_svg_(self):
        return """<svg width="100px" height="100px">
           <circle cx="50" cy="50" r="20" stroke="black" stroke-width="1" fill="blue"/>
        </svg>"""
    
    def _repr_latex_(self):
        return r"$\bigcirc \LaTeX$"
```

Jason Grout

unread,
Jan 19, 2017, 10:59:31 AM1/19/17
to Project Jupyter

You'll also want to generate a unique ID every time you display, so you don't have the issue of having multiple elements with the same id on the page.

Jason


--
You received this message because you are subscribed to the Google Groups "Project Jupyter" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jupyter+u...@googlegroups.com.
To post to this group, send email to jup...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jupyter/906c60db-c0cf-44a7-aa6f-23f664198265%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Björn Johansson

unread,
Jan 20, 2017, 4:59:09 AM1/20/17
to Project Jupyter
I realize that this would be simpler, would there be any possible downside?
Are there situations where no html is generated for the _repr_javascript?

Björn Johansson

unread,
Jan 20, 2017, 5:01:48 AM1/20/17
to Project Jupyter, ja...@jasongrout.org
yes, thanks I saw that when I run the script several times in the notebook, they all get updated. This explains the use of uuids in some code that that I found when searching fro examples.

Björn Johansson

unread,
Jan 20, 2017, 5:02:43 AM1/20/17
to Project Jupyter
btw thanks for the reply!


On Thursday, January 19, 2017 at 11:38:32 AM UTC, Steven Silvester wrote:

Steven Silvester

unread,
Jan 20, 2017, 6:20:45 AM1/20/17
to Project Jupyter
The downside is that in a untrusted notebook the HTML would be stripped.  If you wanted a placeholder in such a scenario, you could use your original approach of stuffing advanced HTML into the JavaScript repr.


On Sunday, January 15, 2017 at 10:28:32 AM UTC-6, Björn Johansson wrote:

Jason Grout

unread,
Jan 20, 2017, 8:32:16 AM1/20/17
to Project Jupyter
Won't the javascript repr also be stripped in an untrusted notebook?

--
You received this message because you are subscribed to the Google Groups "Project Jupyter" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jupyter+u...@googlegroups.com.
To post to this group, send email to jup...@googlegroups.com.

Steven Silvester

unread,
Jan 20, 2017, 8:38:46 AM1/20/17
to Project Jupyter
Right, I meant that a subset of HTML could be used in the html_repr as a fallback display in an untrusted notebook.


On Sunday, January 15, 2017 at 10:28:32 AM UTC-6, Björn Johansson wrote:

Tony Hirst

unread,
Jan 14, 2018, 11:25:43 AM1/14/18
to Project Jupyter
Loosely related to this, a simple cell magic for writing to an HTML 2D canvas element: https://github.com/psychemedia/ipython_magic_canvas

--tony

Björn Johansson

unread,
Jan 15, 2018, 1:25:14 AM1/15/18
to Project Jupyter
That looks very interesting. I am still looking for ways to do this for a more complex class. My problem is that 
I havent managed to penetrate into javascript very well and all the concepts and especially the multitude of frameworks 
still confuses. 
Reply all
Reply to author
Forward
0 new messages