23 May, 2013

Domkol is a Javascript library I wrote to visualize complex functions in a web browser.

The basic problem with visualizing a complex function is that the graph of a complex
function exists in a 2-dimensional complex space, which is equivalent to a *four*
dimensional real number space.

Whereas, one's computer screen only has two dimensions.

One way to solve the problem of not enough dimensions is to use a two-dimensional colour space to represent
the value of a function **f**, where the complex **domain** is represented by the two dimensional
screen, and the value of **f(z)** is represented by the colour value at the position representing
**z**. This is called **domain colouring**.

One problem with domain colouring is that it does not give the viewer a strong feel
for the *shape* of a function. We can distinguish different colours, and we can perceive graduations
in colour, but it is hard to get a good feel for the rate at which colour is changing at any
particular location in the domain.

On the other hand, it is relatively easy to show the shape of a function from a one dimensional space to another one-dimensional space. It is even easy to show a function from a one dimensional space to a two-dimensional space if one represents the graph as two separate graphs, one for each component dimension of the range (i.e. the target space).

So, I hit on the idea of showing the value of a complex function on a one-dimensional subset of the complex domain, with the intention that the user could interatively move the one-dimensional subset around.

I could have chosen a straight line as my subset. But there are some interesting theorems
in complex analysis about the values of a complex function on, inside or outside a closed curve, so I
decided it would be interesting to choose a circle. (To be precise, the *circumference* of a circle.
Also, one could easily have the option of either a line or a circle, but so far I have only implemented
a circle.)

I decided to program the visualization so that there was an initial circle showing the graph
of **f** over the circle, and then the user could choose to manipulate the circle by moving it around
and by changing its radius.

To display the value of the function **f** on the circle, it would be necessary to show each of the
real and imaginary components of the value of **f** as a graph that somehow related to the circle.

The simplest way to do this is to use a form of polar coordinates where the angle coordinate corresponds
to the location of **z** on the circle, and the radial coordinate corresponds to the real or imaginary
component of **f(z)**, where zero is on the circle, positive is outside the circle and negative is inside
the circle.

There is a problem with this method of displaying the graph when overly negative values want to be a negative distance from the centre of the circle, and they "come out the other side". But this can be mitigated by providing an option to scale the graph size.

To emphasize that polar coordinates are being used, a polar coordinate grid should also be shown (and this adjusts accordingly when the graph is scaled).

I wrote Javascript code to make all this happen, but I wasn't completedly satisfied with the result.
A consequence of the **residue theorem** is that the number of phase rotations of **f(z)** as **z** goes
round the circle is equal to the number of simple zeroes *inside* the circle. You can sort of see
this looking at two separate graphs for the real and imaginary components of **f(z)**, but it requires
a certain amount of thinking to interpret the in and out motion of the two graphs.

I realised it would be much easier to see the phase rotation if I combined the two component graphs
into a single three-dimensional graph where, for example, the real component of **f(z)** is represented
by radial distance, as before, and the imaginary component is represented by height above the screen.

Now I was back to not having enough dimensions. I needed at least one more dimension than the two dimensions of the screen. Did I need to rewrite everything from scratch as a WebGL 3D application? Or, could I get away with some kind of "poor man's 3D"?

Inspired by the example of "3D-wiggle" GIF files, I decided to see what I could do.

So, I added some Javascript animation to my page script, and I set it to alternate between two views of the intended 3D graph (and without particularly altering the accompanying domain colouring bitmap).

Unfortunately the result was not very convincing. There was movement, but I could not really "see" the 3D the way it was meant to be.

I tried a number of 3D hints, including rendering the path as a dashed path, to emphasize the actual direction of motion, and shadows, to give a sense of height.

In the end I found one simple but very critical hint, which is to correctly display whether or not the
graph of **f** was going under or over the circle, and to thicken both the circle and the graph line
to emphasize which was on top of the other.

To enable this, it was necessary to split the graph of **f(z)**, represented as an SVG **<path>**
element, into two distinct **<path>** elements – one for the "over"
part of the graph, and one for the "under"
part. Once that is done, CSS "z-index" ordering is all that is required to display the "over" and "under"
correctly.

Also, once the path was split into two parts it was easy use opacity to place the "over" and "under" graphs over and under the HTML canvas element displaying the domain colouring, and set the canvas to be slightly transparent – not enough to make the domain colouring too faded, but enough to see the "under" part of the graph as if looking at it through a murky piece of coloured glass.

So, finally, I made the 3D graph look 3D using these mechanisms:

- Thicken the circle and graph curve to easily see which is over and which is under.
- Display "over" and "under" components of the graph over and under the partly transparent domain coloured canvas.
- Display two faint shadows of the "over" component falling onto the canvas.
- "Wiggle" the graph sideways.

The original intention with the "wiggling" was to wiggle the viewpoint, as typically happens with wiggling GIF's, however what I did in practice was wiggle the graph itself (at least that is what you perceive when you look at it), so that it looks like the graph is moving, but the domain coloured canvas is still.

I also programmed the wiggle to be a harmonic vibration back and forth, as opposed to a wiggle between two positions, or a back-and-forth motion at constant speed in both directions. A harmonic vibration feels smoother and more natural when you watch it, presumably because it is a more physically plausible motion.

Although the 3D view of the graph of **f** on the circle looks cool, there is slightly greater precision
in the 2D view. To allow for maximum user choice, Domkol incorporates several options for controlling
the display of the value of **f** on the circle:

- The circle can be moved around by dragging a handle at the center of the circle.
- The circle's radius can be adjusted by dragging a handle on the edge of the circle.
- The circle and the accompanying graph can be hidden altogether (so that you can, if you want to, just admire the domain colouring without any other distraction).
- The
*scale*of the graph of**f**can be adjusted using a slider. The slider adjusts on a logarithmic scale. If the graph scale is too small, then the graph will not be clearly separated from the circle. If the negative radial values are too large, the graph will "come out the other side" of the centre of the circle, which is confusing to look at. If the positive radial values are too large, the graph will disappear off the edge of the displayed portion of the complex plane. In all these cases, you will want to adjust the scale accordingly. - The graph can be switched between 2D mode, with separate real and imaginary graphs, and thinner paths for the graphs and the circle; and 3D mode, with a single 3D complex graph, with thicker paths.
- In 3D mode, the "wiggle" can be turned on and off.
- Also, the value of
**f**can be "rotated", which means multiplying it by a value of**e**. (When you do this, it may appear that you are rotating the graph around the centre of the circle, but actually you are rotating it around the^{iθ}*circumference*of the circle.)

Using Domkol to explore just one complex function gets a bit boring after a while. More interesting is to be able to explore different functions. Even more interesting is the ability to interactively alter the complex function currently being explored.

For a complex polynomial, such as **f(z) = z ^{3}**, a natural interaction is to be able to
alter the

This interaction can be achieved by creating some draggable "handles", one for each zero of the polynomial.

We can rewrite the function **z ^{3} = (z-a)(z-b)(z-c)**, where

Domkol has two external library dependencies:

- JQuery (latest stable 1.9.x version 1.9.1)
- JQuery UI (latest stable version 1.10.2)

These were the latest stable versions as at the time of writing Domkol (since then, JQuery UI has moved on to 1.10.3).

In JQuery UI, sliders are configured so that page up and page down keys move 20% of the slider length, i.e. there are 5 "pages" from one end of the slider to the other. This value is hard-coded, and there is no option to change it.

For the "rotate function" slider, I found that it would be best to have 4 "pages" in the slider, as these could then naturally correspond to 90 degrees of rotation per page, with the centre point being 0 degrees of rotation.

So I have included (in my web page examples) an altered version of JQuery UI which changes the hard-coded 5 pages to 4 pages.

An ideal solution would be to add this as a configurable option to JQuery UI sliders, and then make a pull request to have this added into the JQuery UI. But I have not done this.

There is no major consequence to using the standard un-altered JQuery UI – one just loses the ability to do easy 90 degree rotations.

As an application in a web page, Domkol has two major components:

- The complex plane
- The control dialog

As DOM components, the control dialog is constructed in HTML, and there isn't too much to say about that.
Except I will say that if you want to achieve a tabular style layout without actually using **<table>**,
then the CSS property **display:inline-block** is your friend, because you can have a **<div>**
with block-like display properties *inside* the div, but inline-style layout relative to its siblings
in the parent HTML element that contains it.

The complex plane includes the following functional components:

- A domain colouring of the complex plane
- A labelled coordinate grid for the complex plane
- The circle graph, with circle, actual graph, optional shadows and polar coordinate grid
- If relevant, draggable handles of function parameters, such as zeroes of a polynomial

These functional components are implemented within the following DOM elements:

- A top-level
**<div>**, which contains the next four elements as absolutely positioned children. - An
**<svg>**element containing the "under" part of the 3D function graph. - The
**<canvas>**element that shows the domain colouring. - An
**<svg>**element that contains all the other SVG elements, including the circle, centre and edge handles for the circle, the polar coordinate grid, the "over" part of the 3D function graph, including shadows, both 2D function graphs, and the labelled coordinate grid. - A
**<div>**element where any number handles are created (where each handle will be in a child**<div>**element)

The first working version of Domkol consisted of a mixture of static HTML, SVG, CSS and Javascript.

It worked like it was meant to, but I realised that if I wanted to make the Javascript *reuseable*
as a library, most of what was in the static HTML and SVG had to be moved into the Javascript.

Which means I had to write Javascript to create the HTML and the SVG elements.

There are three ways that come to mind to create DOM elements in Javascript:

- Plain Javascript
- JQuery
- Some other library

I was already depending on JQuery, but I didn't want to add any more unnecessary dependencies, so I decided to see how far I could get just using JQuery to construct and populate the DOM elements.

As it happens, JQuery doesn't actually *do* construction of SVG elements, so I had to use
plain Javascript for that, with the help of a convenience **createSvgElement** function.

Domkol uses two different graphical features of HTML5: Canvas and SVG.

When you look at the web markup, both Canvas and SVG look like they are fully part of HTML, in the sense
that they use plain tags **<canvas>** and **<svg>**. In particular, for SVG,
there is no XML namespace.

However, this is partly an illusion, as actually SVG elements really *are* embedded
XML elements with their own special namespace. It's just that HTML5 hides this detail from
the user. Also SVG elements are somewhat different from HTML DOM elements, for example
they do not support **innerHTML**, so JQuery methods that use innerHTML to construct
or edit DOM elements just don't work with SVG.

Also, the JQuery UI **draggable** method does not work on SVG elements, because it
depends on attributes which SVG elements do not respond to (or what is actually worse, they
may or may not respond to them, depending on the browser).

So a few work-arounds were required to get SVG to work with JQuery and JQuery UI, some of
them which I found by Googling and surfing StackOverflow. And for cases where one wants to apply
**draggable** to an SVG **<g>** element, for example with the "number handles" that consist
of a small circular dot grouped together with a text label, I could not find a way to get **draggable**
to work cross-browser, so I gave up and reimplemented the number handles in pure HTML, as
separate **<div>** elements.

Javascript does not have any built-in representation of complex numbers. It is possible to
define a class **Complex** with properties **real** and **imaginary**. However this
creates a lot of overhead for each complex number.

A more lightweight approach, which I have used in Domkol, is to represent
a complex number as an array of two real numbers, so that **z = x + iy** is represented by
the Javascript array **[x,y]**. Even this approach creates overhead because there will be constant
creation and garbage collection of two element arrays, but one would expect that to be much cheaper than
creating full Javascript objects (ideally I should do some performance testing to verify that
assumption).

If I felt the need to optimize further, I would consider using parallel arrays to represent
arrays of complex numbers, so that for example,
**z _{1}, z_{2}, z_{3} = x_{1}+y_{1}, x_{2}+y_{2}, x_{3}+y_{3}**
would be represented by

Another more exciting optimisation possibility is **asm.js**. This is a new technology currently
only available in "Firefox nightly", but it is a technology which promises to allow Javascript code
doing a lot of arithmetic to run at a speed not that many times slower than "native" speed. (As I understand it,
you would have to write the code you want optimised according to the special rules of asm.js,
and all your data arrays would have to be constructed as strongly typed data arrays,
but you could separate the code that needs to be optimized from the rest of the code, and have the
rest of your code call the optimised code just like it was calling any other Javascript code.)

In the implementation of Domkol I also used arrays to represent other pairs and triples of numbers that represent 2D and 3D values, such as:

- Points in "pixel space"
- Dimensions of rectangles as width and height in pixels
- 3D points in the pixel coordinate system consisting of actual 2D screen coordinates plus a notional height in pixels above (or below) the screen

**ControlDialogElements** is responsible for the construction of the DOM tree representing
the control dialog. It does not implement the functionality of the control dialog, however it
does save references to those elements to which functionality will be attached. These references are
saved as the following properties on the object: **div** (the top-level div),
**windowTopBar**, **formulaText**, **functionInstructionsText**, **functionScaleSlider**,
**functionScaleText**, **colourScaleSlider**,**colourScaleText**, **showCircleGraphCheckbox**,
**show3DGraphCheckbox**, **wiggleCheckbox**, **rotateGraphSlider**, **graphRotationText**,
**showCoordinateGridCheckbox** and **repaintContinuouslyCheckbox**.
The constructor function for **ControlDialogElements** takes one argument which is the
pre-existing **<div>** element that the control
dialog DOM tree will be inserted into.

**ControlDialog** represents the active functionality of the control dialog. Its constructor
function has one argument which is an object with the DOM element properties that **ControlDialogElements**
has. Configuration of **ControlDialog** occurs by invoking two major methods. First there is
**initialize** which is called in the constructor. **initialize** calls "initialize" methods for each
individual component that requires initialization. The "initialize" method for each control does two things – it
finishes constructing the control, and it saves initial values represented by the initial states of the controls.
For example, for each slider, the "initialize" method constructs the actual JQueryUI slider, and
it configures the slider to trigger a corresponding event when the slider is moved. To give a specific
example, the graph rotation slider is configured to trigger "graphRotationChanged" events. The initial value
for the graph rotation (based on the initial state of the slider) is saved into the **graphRotation**
property of the **ControlDialog.values** object.

The second major method of **ControlDialog** is the **connect** method, which is used to connect the
control dialog to the **ComplexFunctionExplorerView** object (which I have not yet described). This calls
individual "connect" methods to connect individual components to the corresponding components of the
**ComplexFunctionExplorerView** object.

**ExplorerViewElements** is similar to **ControlDialogElements** in that it is responsible for constructing
a DOM tree and saving references to the elements providing functionality, in this case for the "explorer view"
(or "complex function explorer view") which consists of the view into the complex function consisting of the domain
colouring, the complex plane coordinate grid, the graph of the function on the circle, and optionally, any number
handles that may be used to manipulate the function. The constructor function for **ControlDialogElements**
takes four arguments:

- The
**<div>**element that the explorer view will be constructed in - The location of the origin in the pixel coordinates of the canvas element (as a 2-element array)
- The dimension of the canvas in pixels (as a 2-element array)
- The initial radius of the graph circle in pixels

The supplied dimensions do not fully define the view, in particular the "pixels per unit" value has not yet been specified. However these are all the dimensions required to initially construct the DOM tree.

There is an **initialize** method, which calls four "initialize" methods which construct the four
major components of the DOM tree, that is: the canvas, the SVG element for the "under" part of the 3D path,
the SVG element for everything else "above" the canvas, and the **<div>** element which will contain
any number handles that are created. References to elements saved as properties are **canvas**,
**realPathUnder**, **coordinates**, **coordinatesGroup**, **axes**, **unitCoordinateGrid**,
**fineCoordinateGrid**, **circleGraph**, **bigCircle**, **polarGrid**, **polarGridCoarse**,
**realPath**, **realPathShadow**, **realPathShadow2**, **imaginaryPath**, **centreHandle**,
**edgeHandle** and **handlesDiv**.

(Note: because the explorer view is *mostly* SVG elements, whereas the control dialog is
entirely HTML, and JQuery works well with HTML but not so well with SVG, I have adopted different
conventions for storing element references in **ControlDialogElements** and **ExplorerViewElements**
– in **ControlDialogElements** the references are all JQuery wrappers, whereas in
**ExplorerViewElements** the references are all actual DOM objects.)

**DomainCircle** represents the model of the circle in the domain
for which the value of the function **f** will be displayed
as two 2D graphs or one 3D graph. The model includes the actual location of the circle, as well
as other attributes that affect the calculation and display of the function graph.

Attributes of the domain circle include:

**circumferenceIncrementInPixels**– how often the graph value will be recalculated going around the circumference (which defaults to 1)**centreHandlePosition****edgeHandlePosition****radius****graphRotation****wiggleAngle****explorerModel**– a reference to the main model, an object of class**ComplexFunctionExplorerModel**(which see in next section)

**ComplexFunctionExplorerModel** represents a model of the state of exploration of the complex function.

Its attributes are:

**f**– the actual function, as a function with one complex argument that returns a complex value, with complex numbers represented as two element arrays**pixelsPerUnit**– how many pixels represent a distance of 1 in the complex plane (this is the same vertically and horizontally, so there is no option to have a different aspect ratio).**originPixelLocation**,**pixelsDimension**and**circleRadius**– these correspond to the values defined for the**ExplorerViewElements**object**domainCircle**– a reference to the**DomainCircle**model object

The **ComplexFunctionExplorerModel** object contains all the information required to render the
view of the complex function, including the domain colouring and the circle graph, but the view is itself
defined by view objects which contain the references to the required DOM elements, as well as references
to the model objects.

**DomainCircleView** is the view object for the circle graph. It includes attributes for the DOM elements
representing the circle, the centre and edge handles, the polar grid, and all components of the 2D and 3D graphs
(both "over" and "under"). It is responsible for managing the user's interaction with the centre and edge handles.

**ComplexFunction** is an object that represents the complex function being visualized. It contains the
function itself, and an attribute for the function formula. It has methods to trigger "formulaChanged" and
"functionChanged" events for the benefit of objects that need to update themselves when the function is changed
interactively by the user.

**PolynomialFunction** is a specialization of **ComplexFunction** that defines a polynomial function
in terms of an array of zeroes, which supports interaction where the function can be changed by changing the values
of the zeroes.

**CoordinatesView** represents the real and imaginary axes and coordinate grid of the complex plane,
with associated labels.

**ComplexNumberHandle** represents a draggable "number handle", which allows the user to control the
value of a particular number by dragging its handle around the complex plane. This is currently used for exploring
polynomial functions by allowing the user the drag the polynomial zeroes around. But it could be used to
control parameters for any type of complex function.

It is constructed from four parameters:

**complexFunctionExplorerView**– the**ComplexFunctionExplorerView**object that hosts the handles**handlesDiv**– the**<div>**element which is the parent DOM element of the**<div>**for the handle**index**– the unique numerical index for this handle**number**– the initial value of the number

When the number handle is dragged, it triggers "numberChanged" events with three additional parameters:

- the
**index**attribute - the value of the complex number
- true if the value is stilling changing (because the user is still dragging), or false if it has finished changing

**ComplexFunctionExplorerView** is the main view object representing the view of the function in the
complex plane, including the domain colouring, the circle graph, the coordinate axes and grid, and any number handles.

**createExplorerView** is the top-level function which should be called from within a web page in order to create the
**ComplexFunctionExplorerView** object.

It takes seven parameters, which are:

- The JQuery selector for the existing div element into which the view's DOM tree will be inserted
- An object of type
**ComplexFunction**or**PolynomialFunction**representing the function to be explored - A set of initial model values, as provided by the
**values**property of a**ControlDialog**object - The number of pixels per unit (i.e. how many pixels represent a distance of 1.0 in the complex plane?)
- Pixel location of complex origin (as a two element array)
- Width and height of complex plane in pixels (as a two element array)
- Initial radius in pixels of the circle

Note that pixel locations follow the convention that [0,0] is the left-most and top-most point. It follows that
the "x" coordinate in pixel coordinates *increases* when the real component of the complex number increases, whereas
the "y" coordinate in pixel coordinates *decreases* when the imaginary component of the complex number increases.

In Javascript there are two basic ways of connecting objects.

The first is where object A wants to tell object B what to do. In this case a method call is sufficient:

A={}; B={}; B.doSomething = function() { alert("B is doing something"); }; A.makeBDoSomething = function() { B.doSomething(); }; A.makeBDoSomething();

The second case is where object A wants object B to tell it (object A) to do something. This is a bit more indirect, because the object initiating the connection (object A) is not the object initiating the action (object B).

But there is a way to do this based on **events**, and as it happens, Javascript
provides event handling as a basic feature of the language.

Actually, creating your own events (as opposed to builtin browser DOM events) is a little tricky in Javascript, so I'll give an example of how to do it in JQuery. Like this:

A={}; B={}; A.doSomething = function(stuff) { alert("A is doing some stuff: " + stuff); }; $(B).on("peopleNeedToDoStuff", function(event, stuff) { A.doSomething(stuff); }); B.getStuffDone = function() { $(B).trigger("peopleNeedToDoStuff", ["wash the dishes"]); }; B.getStuffDone();

Here it is B which initiates the *action*, when it triggers
the "peopleNeedToDoStuff" event, but it is A which initiates the *connection*,
i.e. A decides that it should let B tell it (A) what to do.

We *could* do the first example using events, however in that case it
would not make the code particularly easier to read or maintain, so I wouldn't do it
that way myself. (I have seen code where someone has taken a "do *everything*
in events" approach, and one ends up with code that's harder to read, and
it can degenerate into incomprehensible and overly verbose "event spaghetti".)

There is a simple rule for deciding between events and direct method calls in Model/View architectures. Which is that if the model is not allowed to "know" about the view, then any time that the model needs to invoke an action on the view, the invocation has to occur via an event. That is, the model triggers the event, but the view initiates the connection which causes it to be registered as a handler for the model's event.

Conversely, if the view needs to invoke an action on the model, a simple method call will probably suffice.

One can also understand event handling in terms of "what", "how" and "who".
A basic feature of object-oriented programming,
or even procedural programming, is that when you invoke a method or function, the caller is specifying
*what* to do, but the callee is the one that knows *how* to do it. When events are used to manage
the flow of control, the caller knows *what* is to be done, but it doesn't even know (at least not in advance)
*who* is going to do it. Also, the caller doesn't even have to know if *anyone* is going to do it,
and, in some cases, there may be more than one "who".

There are five different sources of custom events in Domkol, which are:

- Controls within the control dialog
- The
**ComplexFunctionExplorerView**, for values changed by the control dialog which need to be displayed somewhere (actually in the control dialog itself in most cases) - The wrapper for draggable SVG elements (the wrapper being part of the work-around
that fixes an issue when attempting to use JQuery UI
**draggable**on SVG elements) - Draggable number handles, for when the user changes a number by dragging it around
- Complex function objects, for when a function (and its formula) is changed by user interaction

When you create a Javascript library which can be called from other Javascript files, you have to put at least one object into a global variable of the web page being executed.

It is considered good practice not to create more than one such global value per library, and this value should represent the library itself.

This library object should be populated with properties representing the high-level classes and functions which you intend the user of your library to call.

There are various ways to do this. For Domkol I used the relatively straightforward approach of:

var DOMKOL = {}; (function(lib) { ... lots of internal definitions // exports lib.ControlDialogElements = ControlDialogElements; lib.ControlDialog = ControlDialog; lib.PolynomialFunction = PolynomialFunction; lib.ComplexFunction = ComplexFunction; lib.createExplorerView = createExplorerView; })(DOMKOL);

Here **DOMKOL** is the global variable holding the library object,
and **ControlDialogElements**, **ControlDialog**, **PolynomialFunction**,
**ComplexFunction** and **createExplorerView** are the top-level
classes and functions that I wish to export.

(In the actual **domkol.js** I export various other definitions just in case
the user wants greater access to the internals of the library. You can export a whole
lot of stuff from a library if you want to – the overheads of doing so are minimal,
and it's between you and your library's users whether you are giving them enough rope
to hang themselves.)

Examples of how to configure Domkol can be found in the Javascript files included in the example pages for cubic polynomial, quintic polynomial and exponential function.

The basic steps required are:

- Construct an element of type
**DOMKOL.ControlDialogElements**from the JQuery selector for an existing**<div>**element that is going to contain the control dialog. (This div is assumed to be positioned wherever it is you want the control dialog to be.) - Construct the
**DOMKOL.ControlDialog**object from the**ControlDialogElements**object. - Optionally, add any function-specific instructions to the
**ControlDialog**object using the**addFunctionInstructions**method. - Construct an object of type
**DOMKOL.ComplexFunction**or**DOMKOL.PolynomialFunction**(or make your own function that extends**ComplexFunction**or which satisfies the same interface). - Invoke
**DOMKOL.createExplorerView**to construct the**ComplexFunctionExplorerView**object. - Optionally, create and connect any required number handles.
- Invoke the
**ControlDialog.connect**method on the**ControlDialog**object with the**ComplexFunctionExplorerView**object as parameter to connect the two objects together.

And that's it.

The easiest way to get your own example working using **domkol.js** is probably to cut and paste
one of the existing examples, and then adjust accordingly (that's how I'd do it).