dual_canvas
Javascript quick reference.¶This document is part of the
`jp_doodle` (https://github.com/AaronWatters/jp_doodle)
package.
It provides a quick reference
to using the dual_canvas
Javascript API to build visualizations in
web contexts (including Jupyter notebooks).
The dual_canvas
mechanism is designed to make it easy to develop special
purpose interactive scientific visualizations in web contexts.
A dual_canvas
widget built using the Javascript interface
can be used to build interactive and animated visualizations that live inside
any HTML 5 web page. Discussions below illustrate how to create a canvas, draw things on the
canvas, modify and animate elements of a canvas, and associate mouse event actions to elements of a
canvas, among other topics.
About this document: This document is an executable Jupyter notebook, or another document format
derived from the notebook. The next "code cell" imports external functionality used in the notebook.
In the following discussion
we use the eg.show(demo)
helper to optionally embed an image into
this notebook in order to facilitate file format conversion. Please replace
this helper with display(demo)
when you emulate these code fragments.
# This qr_helper module provides helper functionality for displaying this quick reference.
import qr_helper as eg
eg.DO_EMBEDDINGS = False # flag indicates whether to embed images in the notebook or not (for format conversions)
The Javascript API for dual canvases may be used in any web context.
In standard
web pages a dual_canvas
is implemented as a jQueryUI plug in component.
In Jupyter notebooks a dual_canvas
is "wrapped" as a widget.
The dual canvas functionality
requires jQuery
and jQueryUI
in addition to the canvas object implementation
files canvas_2d_widget_helper.js
and dual_canvas_helper.js
.
Below is a complete
"Hello world" HTML file
which draws a dual canvas in a target
location on a web page. It pulls required style sheets and Javascript libraries from github.io
.
eg.html_hello_world()
It is often useful to use the Javascript API with a canvas created in a Jupyter widget.
The following shows how to create a DualCanvasWidget
and draw objects on the canvas
using the Javascript API directly.
Note: Following example canvases imported from the eg
helper module omit
the details of creating the canvas and providing reference axes to make the presentation
more compact. Only the Javascript code of interest is shown.
from jp_doodle import dual_canvas
from IPython.display import display
def widget_with_javascript():
# Create a canvas and then use Javascript to draw on it.
demo = dual_canvas.DualCanvasWidget(width=420, height=120, font="italic 12px Courier",)
# Put some reference marks on the canvas to illustrate the coordinate space.
demo.js_init("""
// Javascript code:
element.text({x:0, y:0, text:"0,0", color:"red", background:"yellow"} );
element.text({x:410, y:110, text:"410,110", align:"right", color:"red", background:"yellow"} );
element.lower_left_axes({min_x:10, min_y:10, max_x:410,
max_y:110, x_anchor:100, y_anchor:40, max_tick_count:7, color:"blue"})
""")
eg.show(demo) # replace with display(demo)
widget_with_javascript()
eg.js_frame_example()
eg.js_2_frame_example()
eg.js_line_example()
eg.js_arrow_example()
eg.js_double_arrow_example()
eg.js_polyline_example()
eg.js_polygon_example()
eg.js_circle_example()
eg.js_frame_circle_example()
eg.js_star_example()
eg.js_rect_example()
eg.js_canvas_rect_example()
eg.js_text_example()
eg.js_full_image_example()
Note: The canvas created above is marked "tainted" because it loads an image from a remote origin and security restrictions in the browser prevent the canvas from being converted to an image. Here is a screen capture of the live canvas when executed:
eg.js_part_image_example()
Note: The canvas created above is marked "tainted" because it loads an image from a remote origin and security restrictions in the browser prevent the canvas from being converted to an image. Here is a screen capture of the live canvas when executed:
eg.js_axes_example()
Objects which have been explicitly named can be changed (moved, resized, deleted, transitioned, etcetera) and unless events are disabled for the object the object can respond to mouse events (mouse over, click, etcetera).
The object.on(etype, callback)
attaches a callback
to be called when the object
recieves an event of type etype
.
eg.js_event_example()
eg.js_no_name_no_event_example()
eg.js_event_top_only_example()
Named objects have methods which allow them to be modified or related to interactive events.
Below the options
are mappings such as {x:10, y:-29, color:"blue"}
.
// Change the object options.
object.change(changed_options)
// Transition the object options over a time period. Duration defaults to 1 if omitted.
object.transition(changed_options, seconds_duration)
// Make the object invisible and unresponsive to events
object.visible(false)
// Make the object visible and enable event bindings.
object.visible(true)
// Remove the object from the canvas and dispose of it.
object.forget()
// Attach an event handler to call when event_type effects the object.
object.on(event_type, handler)
// Detach any event handler associated with event_type for the object.
object.off(event_type)
Event types include click
, mousedown
, mouseup
, mouseout
, mouseover
, mousemove
, keydown
among others. Please see
https://developer.mozilla.org/en-US/docs/Web/Events
and https://api.jquery.com/on/
for more information about events.
Objects can be identified by name and modified using methods attached to the canvas widget.
// Change object properties by object name.
element.change(name, changed_options)
// Destroy objects with a sequence of names.
canvas.forget_objects(names)
// Show or hide objects identified by a name sequence.
canvas.set_visibilities(names, visibility)
// Add an event binding to an object by name or the whole canvas if for_name is None.
canvas.on_canvas_event(event_type, callback, for_name=None, abbreviated=True, delay=True)
// Remove an event binding from an object by name or from the whole canvas if for_name is None.
canvas.off_canvas_event(event_type, for_name=None)
Event callbacks receive a dictionary argument event
describing the event.
Descriptive slots include:
event["type"]
gives the type of the event (like click
).event["canvas_name"]
give the name of the object under the event, if any (some events are associated to the canvas and have no target object on the canvas).event["model_location"]
gives the coordinate position on the canvas or reference frame associated with
the event as a dictionary like {'x': -0.21, 'y': 0.28}
.event["reference_frame"]["name"]
gives the name of the reference frame for the canvas if the event
is associated with a reference frame.eg.js_event_callback()
eg.js_mouse_tracking_example()
eg.js_lasso_example()
The following will remove and destroy all objects from a canvas and reset the canvas to its initial configuration.
widget.reset_canvas()
The following will remove and destroy all objects from a canvas and reset a frame to its initial configuration.
frame.reset_frame()
The following will reposition and rescale a frame
frame.set_region(
minx, miny, maxx, maxy,
frame_minx, frame_miny, frame_maxx, frame_maxy)
To support "mode change" operations event handlers for a canvas can
be temporarily disabled using reset_events
:
var saved_event_handlers = element.reset_events();
Later the saved event handler structure can be set back in place
using restore_events
:
element.restore_events(saved_event_handlers);
See the implementation of the do_lasso
in the source code
for an example usage.