Section 14 Interactive Elements, Authored in Javascript
When outputting Web page versions, it is possible to embed a variety of dynamic interactive elements. In a LaTeX/PDF version, these will necessarily need to be replaced by some static substitute, such as a screenshot. See Section 3 for the specifics of embedding instances of the Sage Cell Server, which is more elaborate, and not entirely similar.
Interactives in this section are those for which you provide code you have authored. Generally, the libraries involved to support this have open licenses, though the player for GeoGebra may be an exception. Creating these assumes some familiarity with HTML and Javascript. See Section 15 for more interactives that are perhaps simpler to create or use.
(2018-06-22) Almost everything in this section is under active development and not stable yet. Feel free to experiment and make suggestions and requests. This page takes a while to completely load, so be patient.
Subsection 14.1 HTML5 Canvas
HTML5 introduced the <canvas>
element, which can be thought of a blank slate, a place to draw or write on. So PreTeXt has the <slate>
element for a similar purpose. Generally, but not exclusively, HTML5 writes on a <canvas>
using the Javascript language. We demonstrate this approach to interactive diagrams in this subsection.
The following examples are from David Austin's excellent Understanding Linear Algebra textbook, which can be found at
merganser.math.gvsu.edu/david/linear.algebra/ula/index.html
David's contribution of examples, and assistance designing the PreTeXt elements is greatly appreciated. Alright, let's learn some linear algebra. Yes, there are some learning opportunities in this subsection.
Let \(\vec{x}\) be represented by the red arrow, and \(A\vec{x}\) by the grey arrow, for some particular \(2\times 2\) matrix \(A\text{.}\) Drag the tip of the red arrow to see the grey arrow change.
Checkpoint 14.2.
The interactive in Figure 14.1 shows a vector \(\vec{x}\) in red, and the matrix-vector product \(A\vec{x}\) in grey, for a particular \(2\times 2\) matrix \(A\text{.}\) The four entries of the matrix \(A\) are coded into the interactive. Can you deduce \(A\) simply by using the interactive? Which theorem is the key?
Let \(\vec{x}\) be represented by the red arrow, and \(A\vec{x}\) by the grey arrow, for a \(2\times 2\) matrix \(A\text{.}\) Drag the tip of the red arrow to see the grey arrow change. Or drag the blue sliders to change the numerical values of the four entries of the \(2\times 2\) matrix \(A\text{.}\) You will not see the grey vector until you change the matrix using one of the two sliders on the left. Why is that? What are the eigenvectors of the initial matrix?
The next example has ten <slate>
elements communicating with each other, and arranged with the layout features of a <sidebyside>
(see Section 23).
Parameters \(a\text{,}\) \(b\text{,}\) \(d\text{,}\) and \(e\text{,}\) form a \(2\times 2\) matrix \(A\text{,}\) while \(c\) and \(f\) form a vector \(\vec{b}\text{.}\) The two views of Woody shows the effect of the mapping
Warning 14.5.
If your <interactive>
employs a <slate>
with a @surface
attribute whose value is html
, then you are advised to augment each top-level (HTML) element within the <slate>
with the attribute:
xmlns="http://www.w3.org/1999/xhtml"
This will identify all of the elements within the <slate>
as HTML elements and not as PreTeXt elements. The danger is that elements with the same name in both languages, such as <li>
and <table>
, will be mis-identified. This could be harmless, but could also create chaos, such as disrupting numbering of PreTeXt elements.
See the source code of this document for examples: Figure 14.4 Figure 14.11, Figure 14.15.
Note that the HTML that is output can vary slightly from your source in small, harmless ways, such as empty (self-closing) elements being output with both an opening and a closing tag. Please report any significant discrepancies. Soon this requirement will be enforced in the code.
The following example was contributed by Rick Roesler. The <figure>
is comprised of four <stack>
elements within a <sidebyside>
. By varying the time in the top box, the reader can observe the displacement, velocity, and acceleration of a ball thrown upward with an initial velocity of 30 m/s.
Use the time slider in the top panel to vary the time from 0 sec to 6 sec. Observe how the displacement, velocity, and acceleration vary with time.
Subsection 14.2 D3.js
D3 is a Javascript library for “Data-Driven Documents”, which might greatly enhance some data you wish to display. In short, it uses the animation capabilities of SVG. Available examples seem sensitive to the version of the library, so we have examples using different versions. Use the @version
attribute on <interactive>
to specify the version number. The default is 5
.
The first example uses the force layout and collision detection from Version 3. (The necessary commands are very different in Version 4.) Pretend you are a working shepherding dog. Can you separate, and catch, one of the herd?
This is adapted from a block by Mike Bostock at 3231298
with a GPL license. A similar demonstration, only using an HTML5 canvas is at bl.ocks.org/mbostock/3231307
.
Place your mouse/pointer at the center of the interactive to repel the 200 circles.
Similar, but different, this demonstration of a graph layout uses Version 4 of the library. Technical notes:
We have changed the size of the nodes, and their number, to fit in a smaller space.
The Javascript script uses introspection to size itself, which would be a good general practice.
This is adapted from a block by shimizu at e6209de87cdddde38dadbb746feaf3a3
with a GPL license.
Drag a vertex to a new location to see the graph adjust its layout.
Checkpoint 14.9. Graph Planarity.
Can you move the vertices to new locations such that the resulting graph is planar? (In other words, no edges cross?)
Finally an example that actually uses some data. Here is the description from the original block by Martin Chorley at 7aa53c7bf3e411238ac8aef280bd6581
, provided with an MIT License.
This visualisation uses a D3 force simulation to show the Twitter relationships between the Assembly Members in the Welsh Assembly in terms of the number of times each assembly member has mentioned another assembly member in a tweet.
Twitter relationships were mined on 22/03/2017, and are representative of the conversational relationships on that date. Links between AMs represent a conversational relationship: one AM has mentioned the other. Party colour indicates the direction of the mention.
Hover over the nodes to fade out non-connected nodes.
Rather than using intermediate nodes to create curved links (as in Mike Bostock's block), this adds curves by adding a calculated control point for each edge.
Technical notes:
Once the nodes organize themselves (automatically in the beginning), they cannot be moved.
We have adjusted the margins in an attempt to keep names visible on the right side, but without giving up too much space.
We have adjust the repelling force, and the collision buffer, to better fit the available space.
This example required its own CSS, which we have included as part of the
<interactive>
.The data collected from the Twitter analysis is contained in a JSON file,
mention_network.json
, and where the script loads that file, it has a hardcoded path. So this example is a bit brittle, should that file move.
Hover on the name of an Assembly Member to concentrate on their tweet mentions.
Subsection 14.3 SVG
Entirely similar to using an HTML5 canvas
element (14.1), it is possible to control an SVG element with Javascript. This example is from Mark McClure.
Look carefully at the source and rendering of this example as HTML. The change in \(x\text{,}\) denoted here as \(h\text{,}\) is reported when the “Show secant line” option is ticked. The \(h\) is being rendered as mathematics by the Javascript MathJax library. However, this cannot be accomplished with $...$
nor by \(...\)
, but instead by using <script>
tags that MathJax recognizes. So the employment of MathJax here is accomplished with
<script type="math/tex">h = </script>
Select a function with the radio buttons, then use the checkbox to add the secant line. The denominator of the difference quotient, \(h\text{,}\) can be adjusted with the slider and the red point will react to the different values. The green point is the point of tangency, and can be dragged with the mouse.
Checkpoint 14.12. Changing Secant Lines.
When discussing the derivative as a limit, we think of the point of tangency as being fixed (the green point in 14.11) and the “other” point defining the secant line as changing (the red point in 14.11). Switch it up! Fix a large value of \(h\) (positive or negative) and then change the point of tangency (the green point). Discuss what you observe.
Subsection 14.4 JSXGraph
JSXGraph is a “cross-browser JavaScript library for interactive geometry, function plotting, charting, and data visualization in the web browser.” Now a <slate>
will be what JSXGraph calls a board. Again, you use Javascript to write onto a <slate>
, but have some powerful shortcuts available from the JSXGraph library. For this reason, PreTeXt calls JSXGraph a “language”, similar in may respects to how Sage is a language, but is really a Python library. So realize that the syntax for using JSXGraph is that of Javascript.
Place Javascript inside a file that is specified with the @source
attribute of the <interactive>
element. Then just be certain that @xml:id
of the <interactive>
element is passed as the HTML id
in an (early) call to JSXGraph's initBoard()
method.
The plot below is the curve \(r=a+b\theta\) in polar coordinates, for \(0\leq\theta\leq 8\pi\text{.}\) It may be manipulated with the sliders to control the shape of the curve. Point \(A\) is contrained to the curve, but may be dragged to a new location. At \(A\) the tangent line and normal line are plotted as dashed red lines. Use the controls in the lower left to adjust the viewing window. This example is taken from the JSXGraph example wiki. The code could be written in 7 lines. Width is 80% and aspect ratio is 4:3.
Drag the sliders to change the parameters \(a\) and \(b\text{.}\) Controls in the lower-right will adjust the viewing window.
Here is a more elaborate example, from the JSXGraph Showcase, titled Infinity.
There are two active sliders to control the shape and shading of the graphic, and hovering the mouse near one of the edges will highlight the entirety of one of the 30 quadrangles. Finally, each of the four red corners may be dragged to a new location. Code is 47 lines. Width is 60% and aspect ratio is the default, 1:1, i.e. a square.
Drag the sliders to change the pattern, and drag any of the four red corners to change the overall shape.
Here are the two new examples. They have been included in a sidebyside
layout element with equal widths (see Section 23) so they can be placed horizontally across the page. They are not wrapped as figures, so cannot be cross-referenced. These are again from the example wiki, the left being Fermat's Spiral and the right being a demonstration of B-splines.
Drag the slider to change the curve.
Any of the 8 red control points may be moved anywhere.
Finally, a piecewise function you can control, with traces of the domain values and range values in two other JSXGraph boards. Boards and HTML buttons have been laid out using the sidebyside
layout element.
The slider of the left panel will trace out the piecewise function. Simultaneously, the domain will be traced in the middle panel, and the range in the right panel.
Generally, we load an interactive into an HTML iframe
to sandbox (isolate) it from other interactives. We does this for your own protection. So, for example, one interactive cannot talk to another. If two <slate>
need to communicate, then they are related, and should be placed into a single <interactive>
, allowed to layout themselves, or grouped within a <sidebyside>
allowing finer control. Even if we have this under control, you might still enjoy reading Your JS is a Mess at mikecavaliere.com/your-js-is-a-mess-javascript-namespacing/
.
Subsection 14.5 JessieCode
JessieCode is a scripting language for JSXGraph. It provides the core geometric and graphing features of JSXGraph without accessing the underlying JavaScript. In order to use JessieCode, you simply create the HTML <div>
element as you would for any other JSXGraph interactive plot and then provide the JessieCode script, which focuses on the geometric elements.
Because JessieCode is provided by JSXGraph, the interactive platform is jsxgraph
. The <slate>
, however, uses @surface
with value jessiecode
. The script can be embedded directly in your code. As usual, you would need to remember to escape the special characters. JessieCode uses <
and >
for inequalities as well as for declaring objects used to style geometric elements, and &&
is the boolean AND operator. Alternatively, you can provide the file as a separate resource, providing the URL with a @source
attribute. Attributes defining the JSXBoard at the time it is created should be included as attributes of the <slate>
, including @boundingbox
, @axis
, and @grid
.
For this first example, the JessieCode was included directly in the XML source as the contents of the associated slate.
Use the sliders to set the parameters of the quadratic \(f(x)=ax^2+bx+c\text{.}\) Drag the point \(A\) on the graph and the point \(P\) to define a line. Try to make the line tangent at the point at \(A\) and observe the resulting slope of the tangent line.
For this second example, the JessieCode was included through an associated script file, loaded by the browser.
Drag the point \(B\) to move the point on the graph and change the secant line. Notice that there is no well-defined limiting tangent line as \(x \to 0\text{.}\)
Subsection 14.6 Sage Interacts
Sage, and the Sage Cell Server, support interactive demonstrations, called interacts.
The interactive elements are nearly trivial to construct.
An interact is simply a single Python function (acted on by a decorator).
You have the full mathematical power of Sage at your disposal, so can do some very powerful computations with high precision (or exactly).
The interface is not as polished as what you can achieve with Javascript libraries.
Graphics refresh with a round-trip to the server, so are not nearly as fluid as with other tools.
Note that each interact is insulated from the others, unlike our other employment of the Sage Cell Server.
This example is by Marshall Hampton, taken from the Sage interact wiki, wiki.sagemath.org/interact/calculus
, specifically here.
Subsection 14.7 Geogebra
To embed a GeoGebra applet as-is from GeoGebra's Classroom Resources site (by material ID), see Subsection 15.1. To design your own applet (either from scratch, or modifying something that already exists in one of those three forms) you may use one of Geogebra's “Apps” to embed the material in your document. (But note, use of the App comes with licensing restrictions.) PreTeXt will handle most of the technical details for you.
Do one of the following:
Identify a material ID from GeoGebra's Classroom Resources site. You might even make the material yourself on that site.
Obtain a
.ggb
file from GeoGebra. You might construct something on a desktop installation of GeoGebra and save it. If you have a base64-encoded string for a GeoGebra applet, but you don't have a.ggb
file, you can decode the string and save the result. For example, at www.opinionatedgeek.com/codecs/base64decoder.Obtain a base64 encoded string for a GeoGebra applet. You might first open a
.ggb
file in a desktop installation of GeoGebra, and push ctrl-shift-B (command-shift-B on a Mac) and then the string will be in your clipboard.None of the above, with the intention to make an applet from scratch.
Then mimic the examples that follow, using GeoGebra API commands documented at wiki.geogebra.org/en/Reference:GeoGebra_Apps_API, but do not include the ggbApplet.
or applet.
used in examples to prefix the functions—that part of the code will be provided automatically by PreTeXt.
Jack Green created an applet on the Classroom Resources site with ID D4s2v4ft
, which you may view at geogebra.org/m/D4s2v4ft. Suppose you would like to use this in your project, but change something about it. We will change something trivial, making the \(y\)-axis ticks be separated \(5\) apart instead of \(10\) apart. We also decide we want a different aspect ratio and overall width. One gotcha: the original applet is loaded and then PreTeXt uses @width
and @aspect
attributes to resize the viewing window using the top left corner as an anchor. This does not rescale axes and that may leave you with important elements missing from the viewing window. So here we reset the viewing window to return to values that are in the original. Lastly, we disable zooming, which is not helpful for this applet. To do each of these things, we rely on the GeoGebra API manual at wiki.geogebra.org/en/Reference:GeoGebra_Apps_API. It is important to use one command per line.
The same can be done with a .ggb
file. Here we use two provided by David Rosoff, and one provided by Tevian Dray. The path to the file needs to be relative. First, David's original.
.ggb
fileNow we modify David's applet in a few ways.
.ggb
file.ggb
fileIn this one provided by Tevian Dray, we make no modifications (except for those imposed by the scaling). You will need to zoom out a bit, and then pan over some, to see all the pieces.
Drag some of the points and some of the circles to change them, and watch the remainder react.
You could also use a base64-encoded string of the .ggb
file. You might come across such a string somewhere, or you might generate one by opening a .ggb
file in a desktop installation of GeoGebra, and pushing ctrl-shift-B (command-shift-B on a Mac) to get the string in your clipboard. If you do this, you could use a @base64
attribute in place of the @source
attribute in the previous example. We don't do that here because such a string is generally over 5000 characters long and we are keeping the sample article source a bit cleaner.
Lastly, you may just wish to build something from scratch using GeoGebra API. Note that for accessibilty reasons, some objects are rendered unselectable with the setFixed
command. Perhaps this should have been done with the previous examples, but that is more difficult when you do not know all of their names.
Subsection 14.8 threejs
An example using the threejs
3D Javascript library. This is one of the project's examples 1 , licensed with an MIT License, with minimal modifications. We get several of the necessary libraries from the threejs.org
site.
threejs.org/examples/#webgl_geometry_extrude_splines
threejs
webgl_geometry_extrude_splines example