From the REPL, run
Elem constructor can be used to create an element.
# E.g. using Patchwork Elem(:h1, "Hello, World!")
h1 heading element equivalent to the HTML
You can attach any DOM property (e.g.
width) that you would like the DOM node to have by passing it as a keyword argument to
# E.g. Elem(:h1, "Hello, World!", className="welcome", style=[:color => :white, :backgroundColor => :black])
This creates a
h1 with white text on a black background.
You can of course nest elements inside another
Elem(:div, [ Elem(:h1, "Hello, World!"), Elem(:p, "How are you doing today?")])
Elem objects are immutable
children(::Elem) returns the children of the element as a persistent vector
properties(::Elem) returns the dictionary of its properties. There are some infix operators defined for
& operator can set attributes
# E.g. div_with_class = Elem(:div, "This div's class can change") & [:className => "shiny"]
<< operator can append an element to the end of another.
h1_and_p = Elem(:div, Elem(:h1, "Hello, World!")) << Elem(:p, "How are you doing today?")
SVG graphics are DOM nodes too, and hence can be created in Patchwork.
Elem(:svg, Elem(:circle, cx=250, cy=250, r=100, fill="orange"), width=500, height=500)
draws a circle.
If you are using IJulia, you can use the Interact.jl's
@manipulate statement to draw a circle whose position, radius and color can be changed:
using Interact, Patchwork @manipulate for r=1:100, cx = 1:500, cy=1:400, color=["orange", "green", "blue"] Elem(:svg, Elem(:circle, cx=cx, cy=cy, r=r, fill=color), width=500, height=500) end
diff function computes the difference between two elements.
# E.g. patch = diff(left::Elem, right::Elem)
Returns a "patch". A patch is a
Dict which maps node indices to a list of patches on that node. The node index is a number representing the position of the node in a depth-first ordering starting at the root node (here
left), whose index is 0.
Elems are based on immutable datastructures.
<< operations return new
Elems, which may share structure with the operands. The more structure two nodes share, the faster the diffing.
For example, if you have a big
averybigelem, the running time of the following diff call
diff(averybigelem, averybigelem & [:className => "shiny"])
will not depend on the size and complexity of
averybigelem because diffing gets short-circuited since
left.children === right.children. It will probably be helpful to keep this in mind while building something with Patchwork.
runtime/build.js that needs to be included into a page where you would like to display Patchwork nodes.
This is automatically done for you if you are using Patchwork from IJulia.
Patchwork defines the
At a lower level, the runtime exposes the
window.Patchwork object, which can be used to render nodes from their JSON representations and also apply patches.
// E.g. node = new Patchwork.Node(mountId, elemJSON)
this renders the node represented by
elemJSON and appends it to a DOM element with id
Patchwork.Node instances have an
applyPatch method which can be used to patch the node.
// E.g. node.applyPatch(patchJSON)
If Patchwork is installed, interactive plots or Compose graphics automatically use Patchwork to efficiently render them into SVG Virtual DOM. Any updates to the plot get turned into patches, sent over to the browser and applied to the plot.
When you load Patchwork in IJulia, the runtime is setup automatically for you. If the result of executing a cell is an
Elem object, it gets rendered in the cell's output area.
display(::Elem) will work too.
You will need a recent
To build the JS files run the following from
npm install . npm install -g browserify npm install -g uglifyjs make
6 months ago