<section xml:id="section-interactive-authored" label="section-interactive-authored">
<title>Interactive Elements, Authored in Javascript</title>
<shorttitle>Interactive Elements, Authored</shorttitle>
<plaintitle>Interactive Elements, Authored</plaintitle>
<idx><h>interactive elements</h><h>authored</h></idx>
<idx><h>embedded interactive elements</h><h>authored</h></idx>
<introduction>
<p>
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 <xref ref="section-sage-cells" text="type-global" /> for the specifics of embedding instances of the Sage Cell Server,
which is more elaborate, and not entirely similar.
</p>
<p>
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 <init>HTML</init> and Javascript.
See <xref ref="section-interactive-server" text="type-global" /> for more interactives that are perhaps simpler to create or use.
</p>
<p>
(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.
</p>
</introduction>
<subsection xml:id="interactive-html5-canvas">
<title>HTML5 Canvas</title>
<p>
<init>HTML5</init> introduced the <tag>canvas</tag> element,
which can be thought of a blank slate,
a place to draw or write on.
So <pretext /> has the <tag>slate</tag> element for a similar purpose.
Generally, but not exclusively,
<init>HTML5</init> writes on a <tag>canvas</tag> using the Javascript language.
We demonstrate this approach to interactive diagrams in this subsection.
</p>
<p>
The following examples are from David Austin's excellent
<url href="http://merganser.math.gvsu.edu/david/linear.algebra/ula/index.html" visual="merganser.math.gvsu.edu/david/linear.algebra/ula/index.html">
<pubtitle>Understanding Linear Algebra</pubtitle></url>
textbook, which can be found at
<cd>
<cline>merganser.math.gvsu.edu/david/linear.algebra/ula/index.html</cline>
</cd>
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.
</p>
<figure xml:id="figure-simple-eigenvector">
<caption>A simple eigenvector demonstration</caption>
<interactive xml:id="interactive-simple-eigenvector" platform="javascript" width="60%" source="code/austin/figures.js code/austin/simple-ev.js" preview="preview/simple-eigenvector-preview.jpg">
<slate xml:id="eigenvector" surface="canvas" />
<instructions>
<p>
Let <m>\vec{x}</m> be represented by the red arrow,
and <m>A\vec{x}</m> by the grey arrow,
for some particular <m>2\times 2</m> matrix <m>A</m>.
Drag the <em>tip</em> of the red arrow to see the grey arrow change.
</p>
</instructions>
</interactive>
</figure>
<exercise>
<p>
The interactive in <xref ref="figure-simple-eigenvector" text="type-global" /> shows a vector <m>\vec{x}</m> in red,
and the matrix-vector product <m>A\vec{x}</m> in grey,
for a particular <m>2\times 2</m> matrix <m>A</m>.
The four entries of the matrix <m>A</m> are coded into the interactive.
Can you deduce <m>A</m> simply by using the interactive?
Which theorem is the key?
</p>
</exercise>
<figure xml:id="figure-eigenvectors">
<caption>Eigenvector demonstration</caption>
<interactive xml:id="interactive-eigenvectors" platform="javascript" width="90%" aspect="4:5" source="code/austin/figures.js code/austin/eigenvectors.js" preview="preview/eigenvectors-preview.jpg">
<slate xml:id="sliders" aspect="4:1" surface="canvas" />
<slate xml:id="eigenvectors" aspect="4:4" surface="canvas" />
<instructions>
<p>
Let <m>\vec{x}</m> be represented by the red arrow,
and <m>A\vec{x}</m> by the grey arrow,
for a <m>2\times 2</m> matrix <m>A</m>.
Drag the <em>tip</em> 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 <m>2\times 2</m> matrix <m>A</m>.
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?
</p>
</instructions>
</interactive>
</figure>
<p>
The next example has ten <tag>slate</tag> elements communicating with each other,
and arranged with the layout features of a <tag>sidebyside</tag>
(see <xref ref="section-side-by-side" text="type-global" />).
</p>
<figure xml:id="figure-animation">
<caption>Affine Transformations</caption>
<interactive xml:id="interactive-animation" platform="javascript" width="100%" aspect="12:10" source="code/austin/animation.js" preview="preview/animation-preview.jpg">
<sbsgroup>
<sidebyside>
<slate xml:id="a" surface="canvas" aspect="4:1" />
<slate xml:id="b" surface="canvas" aspect="4:1" />
<slate xml:id="c" surface="canvas" aspect="4:1" />
</sidebyside>
<sidebyside>
<slate xml:id="d" surface="canvas" aspect="4:1" />
<slate xml:id="e" surface="canvas" aspect="4:1" />
<slate xml:id="f" surface="canvas" aspect="4:1" />
</sidebyside>
<sidebyside>
<slate xml:id="left" surface="canvas" aspect="6:6" />
<slate xml:id="right" surface="canvas" aspect="6:6" />
</sidebyside>
<sidebyside width="25%" margins="25% 25%">
<slate surface="html" aspect="3:1">
<button xmlns="http://www.w3.org/1999/xhtml" type="button" id="compose">Compose</button>
</slate>
<slate surface="html" aspect="3:1">
<button xmlns="http://www.w3.org/1999/xhtml" type="button" id="reset">Reset</button>
</slate>
</sidebyside>
</sbsgroup>
<instructions>
<title>Flipping Woody</title>
<p>
Parameters <m>a</m>, <m>b</m>,
<m>d</m>, and <m>e</m>, form a <m>2\times 2</m> matrix <m>A</m>,
while <m>c</m> and <m>f</m> form a vector <m>\vec{b}</m>.
The two views of Woody shows the effect of the mapping
<me>
\vec{x}\mapsto A\vec{x} + \vec{b}
</me>.
</p>
</instructions>
</interactive>
</figure>
<warning>
<p>
If your <tag>interactive</tag> employs a <tag>slate</tag> with a <attr>surface</attr> attribute whose value is <c>html</c>,
then you are advised to augment each top-level (<init>HTML</init>) element within the <tag>slate</tag> with the attribute:
<cd>
<cline>xmlns="http://www.w3.org/1999/xhtml"</cline>
</cd>
This will identify <em>all</em>
of the elements within the <tag>slate</tag> as <init>HTML</init> elements and not as <pretext /> elements.
The danger is that elements with the same name in both languages,
such as <tag>li</tag> and <tag>table</tag>, will be mis-identified.
This could be harmless, but could also create chaos,
such as disrupting numbering of <pretext /> elements.
</p>
<p>
See the source code of this document for examples:
<xref ref="figure-animation" text="type-global" /> <xref ref="figure-interactive-slopes" text="type-global" />, <xref ref="figure-piecewise" text="type-global" />.
</p>
<p>
Note that the <init>HTML</init> 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.
</p>
</warning>
<p>
It is also possible to add <tag>script</tag> elements within an interactive that contain properly escaped JS code.
These elements will be placed at the end of the document created to hold the interactive content and can interactive with the other elements within the interactive but can not directly interact with the surrounding page.
</p>
<p>
Authors are strongly discouraged from trying to incorporate complex code in the form of a <tag>script</tag>,
but it can be a useful tool to call more complex code that is linked via <attr>source</attr> on the <tag>interactive</tag>.
</p>
<p>
This example uses a <tag>script</tag> to draw
<q>Hello World</q>
to a <tag>slate</tag>
</p>
<figure xml:id="figure-simple-js-script">
<caption>A simple embedded script example</caption>
<interactive aspect="6:1" xml:id="interactive-simple-js-script" platform="javascript" source="code/roesler/kinematics.js">
<slate aspect="6:1" xml:id="simple-js-script" surface="canvas" />
<script>
const canvas = document.getElementById("simple-js-script");
const ctx = canvas.getContext("2d");
ctx.font = "40px sans-serif";
ctx.fillText("Hello world", 10, 50);
</script>
</interactive>
</figure>
</subsection>
<subsection>
<title>D3.js</title>
<idx>D3.js</idx>
<p>
<term>D3</term> is a Javascript library for
<q>Data-Driven Documents</q>, which might greatly enhance some data you wish to display.
In short, it uses the animation capabilities of <init>SVG</init>.
Available examples seem sensitive to the version of the library,
so we have examples using different versions.
Use the <attr>version</attr> attribute on <tag>interactive</tag> to specify the version number.
The default is <c>5</c>.
</p>
<p>
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?
</p>
<p>
This is adapted from a
<url href="https://bl.ocks.org/mbostock/3231298" visual="bl.ocks.org/mbostock/3231298">block</url>
by
<url href="https://bl.ocks.org/mbostock" visual="bl.ocks.org/mbostock">Mike Bostock</url>
with a <init>GPL</init> license.
A similar demonstration,
only using an <init>HTML5</init> canvas is at <url href="https://bl.ocks.org/mbostock/3231307" visual="bl.ocks.org/mbostock/3231307" />.
</p>
<figure>
<caption>Force layout and collision detection</caption>
<interactive xml:id="interactive-d3-collision" platform="d3" version="3" width="80%" aspect="1:1" source="code/d3/collision.js" preview="preview/collision-preview.png">
<slate xml:id="d3-collision" surface="div" aspect="1:1" />
<instructions>
<p>
Place your mouse/pointer at the center of the interactive to repel the 200 circles.
</p>
</instructions>
</interactive>
</figure>
<p>
Similar, but different,
this demonstration of a graph layout uses Version 4 of the library.
Technical notes:
<ul>
<li>
We have changed the size of the nodes,
and their number, to fit in a smaller space.
</li>
<li>
The Javascript script uses introspection to size itself,
which would be a good general practice.
</li>
</ul>
</p>
<p>
This is adapted from a
<url href="https://bl.ocks.org/shimizu/e6209de87cdddde38dadbb746feaf3a3" visual="bl.ocks.org/shimizu/e6209de87cdddde38dadbb746feaf3a3">block</url>
by
<url href="https://bl.ocks.org/shimizu" visual="bl.ocks.org/shimizu">shimizu</url>
with a <init>GPL</init> license.
</p>
<figure>
<caption>Graph Layout</caption>
<interactive xml:id="interactive-d3-graph-layout" platform="d3" version="4" width="60%" aspect="1:1" source="code/d3/graph-layout.js" preview="preview/graph-layout-preview.png">
<slate xml:id="d3-graph-layout" surface="div" aspect="1:1" />
<instructions>
<p>
Drag a vertex to a new location to see the graph adjust its layout.
</p>
</instructions>
</interactive>
</figure>
<exercise>
<title>Graph Planarity</title>
<statement>
<p>
Can you move the vertices to new locations such that the resulting graph is planar? (In other words,
no edges cross?)
</p>
</statement>
</exercise>
<p>
Finally an example that actually uses some data.
Here is the description from the
<url href="https://bl.ocks.org/martinjc/7aa53c7bf3e411238ac8aef280bd6581" visual="bl.ocks.org/martinjc/7aa53c7bf3e411238ac8aef280bd6581">original block</url>
by
<url href="https://bl.ocks.org/martinjc" visual="bl.ocks.org/martinjc">Martin Chorley</url>
with an MIT License.
</p>
<blockquote>
<p>
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.
</p>
<p>
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.
</p>
<p>
Hover over the nodes to fade out non-connected nodes.
</p>
<p>
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.
</p>
</blockquote>
<p>
Technical notes:
<ul>
<li>
Once the nodes organize themselves
(automatically in the beginning),
they cannot be moved.
</li>
<li>
We have adjusted the margins in an attempt to keep names visible on the right side,
but without giving up too much space.
</li>
<li>
We have adjust the repelling force,
and the collision buffer, to better fit the available space.
</li>
<li>
This example required its own <init>CSS</init>,
which we have included as part of the <tag>interactive</tag>.
</li>
<li>
The data collected from the Twitter analysis is contained in a <init>JSON</init> file,
<c>mention_network.json</c>,
and where the script loads that file,
it has a hardcoded path.
So this example is a bit brittle, should that file move.
</li>
</ul>
</p>
<figure>
<caption>Tweet mentions within the Welsh Assembly</caption>
<interactive xml:id="interactive-d3-welsh" platform="d3" version="4" width="100%" aspect="1:2" source="code/d3/welsh.js" css="code/d3/welsh.css" preview="preview/welsh-assembly-preview.png">
<slate xml:id="d3-welsh" surface="div" aspect="1:2" />
<instructions>
<p>
Hover on the name of an Assembly Member to concentrate on their tweet mentions.
</p>
</instructions>
</interactive>
</figure>
</subsection>
<subsection xml:id="svg-interactives">
<title>SVG</title>
<p>
Entirely similar to using an HTML5 <c>canvas</c> element
(<xref ref="interactive-html5-canvas" />),
it is possible to control an <init>SVG</init> element with Javascript.
This example is from Mark McClure.
</p>
<p>
Look carefully at the source and rendering of this example as <init>HTML</init>.
The functions to choose from via radio buttons,
and the change in <m>x</m>, denoted later as <m>h</m>,
are being rendered as mathematics by the Javascript MathJax library.
However, this cannot be accomplished with simply <c>$...$</c> nor by simply <c>\(...\)</c>,
but instead by using the <c>\(...\)</c> and then also wrapping that in a <tag>span</tag> element with a <attr>class</attr> attribute set to <c>process-math</c>. (The latter is how we instruct MathJax as to which parts of a page to process, or not).
So to have MathJax render a nice <m>x^2</m> in this context
(math inside <init>HTML</init> inside a <tag>slate</tag> inside an <tag>interactive</tag>)
would be accomplished with
<cd>
<cline><span class="process-math">x^2</span></cline>
</cd>
</p>
<figure xml:id="figure-interactive-slopes">
<caption>Tangent and secant slopes</caption>
<interactive xml:id="interactive-slopes" platform="javascript" width="100%" aspect="6:8" source="https://code.jquery.com/jquery-1.11.3.min.js https://d3js.org/d3.v3.min.js https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.2.1/math.min.js code/mcclure/slope.js" css="code/mcclure/slope.css">
<slate xml:id="function-list" surface="html" aspect="6:2">
<div xmlns="http://www.w3.org/1999/xhtml" class="p">
Calculus consists of those problems in mathematics that can be solved with the
following basic approach:
</div>
<div xmlns="http://www.w3.org/1999/xhtml" class="em_display">
Approximate and take a limit!
</div>
<div xmlns="http://www.w3.org/1999/xhtml" class="p">
The simplest, standard, geometric example of this process is the approximation
of the slope of a tangent line with a secant line.
Here's an illustration of this basic idea.
</div>
<div xmlns="http://www.w3.org/1999/xhtml" id="function_list" style="text-align: center">
Choose <span class="process-math">\(f\)</span>:
<span class="function_radio_container" style="padding-left: 10px">
<input type="radio" class="radio" name="function" value="f1" id="f1" />
<span class="process-math">\(f(x)=x^2\)</span>
</span>
<span class="function_radio_container">
<input type="radio" class="radio" name="function" value="f2" />
<span class="process-math">\(f(x)=\frac{1}{3}e^x\)</span>
</span>
<span class="function_radio_container">
<input type="radio" class="radio" name="function" value="f3" />
<span class="process-math">\(f(x)=\sin(2x^2)+x/4\)</span>
</span>
</div>
</slate>
<slate xml:id="the_graph" surface="svg" aspect="6:4" />
<slate xml:id="info-container" surface="html" aspect="6:2">
<div xmlns="http://www.w3.org/1999/xhtml" id="h_info_container">
<table>
<tr>
<td><table>
<tr><td><input id="show_secant_checkbox" type="checkbox" /> Show secant line</td></tr>
<tr><td><input id="h_slider" type="range" min="-0.5" max="0.5" step="0.01" /></td></tr>
</table></td>
<td><table>
<tr><td class="dimit" style="text-align: left;"><span class="process-math">\(h\)</span> = <span id="h_value_display" /></td></tr>
<tr><td class="dimit" style="text-align: left;">secant slope = <span id="secant_value_display" /></td></tr>
<tr><td style="text-align: left;">tangent slope = <span id="tangent_value_display" /></td></tr>
</table></td>
</tr>
</table>
</div>
</slate>
<instructions>
<p>
Select a function with the radio buttons,
then use the checkbox to add the secant line.
The denominator of the difference quotient, <m>h</m>,
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.
</p>
</instructions>
</interactive>
</figure>
<exercise>
<title>Changing Secant Lines</title>
<statement>
<p>
When discussing the derivative as a limit,
we think of the point of tangency as being fixed
(the green point in <xref ref="figure-interactive-slopes" />)
and the
<q>other</q>
point defining the secant line as changing
(the red point in <xref ref="figure-interactive-slopes" />).
Switch it up!
Fix a large value of <m>h</m>
(positive or negative)
and then change the point of tangency
(the green point).
Discuss what you observe.
</p>
</statement>
</exercise>
</subsection>
<subsection>
<title>JSXGraph</title>
<idx>JSXGraph</idx>
<p>
<url href="http://jsxgraph.uni-bayreuth.de/wp/index.html" visual="jsxgraph.uni-bayreuth.de">JSXGraph</url>
is a
<q>cross-browser JavaScript library for interactive geometry,
function plotting,
charting, and data visualization in the web browser.</q>
Now a <tag>slate</tag> will be what JSXGraph calls a <term>board</term>.
Again, you use Javascript to write onto a <tag>slate</tag>,
but have some powerful shortcuts available from the JSXGraph library.
For this reason, <pretext /> calls JSXGraph a
<q>language</q>, 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.
</p>
<p>
Place Javascript inside a file that is specified with the <attr>source</attr> attribute of the <tag>interactive</tag> element.
Then just be certain that <attr>xml:id</attr> of the <tag>interactive</tag> element is passed as the <init>HTML</init> <c>id</c> in an (early) call to JSXGraph's <c>initBoard()</c> method.
</p>
<p>
The following example was contributed by Rick Roesler.
The <tag>figure</tag> is comprised of four <tag>stack</tag> elements within a <tag>sidebyside</tag>.
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.
</p>
<figure>
<caption>1-Dimensional Kinematics</caption>
<interactive xml:id="kinematics" platform="jsxgraph" aspect="6:7" source="code/roesler/kinematics.js">
<sidebyside width="70%" margins="15%">
<stack>
<slate xml:id="box_t" surface="jsxboard" aspect="6:1" />
<slate xml:id="box_s" surface="jsxboard" aspect="6:3" />
<slate xml:id="box_v" surface="jsxboard" aspect="6:3" />
<slate xml:id="box_a" surface="jsxboard" aspect="6:3" />
</stack>
</sidebyside>
<instructions xml:id="kinematics-instructions">
<p>
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.
</p>
</instructions>
<static>
<image source="images/kinematics.png" width="60%" />
</static>
</interactive>
</figure>
<p>
The plot below is the curve
<m>r=a+b\theta</m> in polar coordinates,
for <m>0\leq\theta\leq 8\pi</m>.
It may be manipulated with the sliders to control the shape of the curve.
Point <m>A</m> is contrained to the curve,
but may be dragged to a new location.
At <m>A</m> 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
<url href="http://jsxgraph.uni-bayreuth.de/wiki/index.php/Archimedean_spiral" visual="jsxgraph.uni-bayreuth.de/wiki/index.php/Archimedean_spiral">Archimedean Spiral</url>
is taken from the
<url href="http://jsxgraph.uni-bayreuth.de/wiki/index.php/Category:Examples" visual="jsxgraph.uni-bayreuth.de/wiki/index.php/Category:Examples">JSXGraph example wiki</url>.
The code could be written in 7 lines.
Width is 80% and aspect ratio is 4:3.
</p>
<figure>
<caption>The Archimedian Spiral <m>r = a + b\theta</m>, <m>0\leq\theta\leq 8\pi</m></caption>
<idx>Archimedian Spiral</idx>
<interactive xml:id="interactive-archimedian-spiral" platform="jsxgraph" width="80%" aspect="4:3" source="code/jsxgraph/archimedian.js">
<slate xml:id="jsxgraph-archimedian-spiral" surface="jsxboard" aspect="4:3" />
<instructions>
<p>
Drag the sliders to change the parameters <m>a</m> and <m>b</m>.
Controls in the lower-right will adjust the viewing window.
</p>
</instructions>
</interactive>
</figure>
<p>
Here is a more elaborate example, from the
<url href="http://jsxgraph.uni-bayreuth.de/showcase/" visual="jsxgraph.uni-bayreuth.de/showcase/">JSXGraph Showcase</url>,
titled
<url href="http://jsxgraph.uni-bayreuth.de/showcase/infinity.html" visual="jsxgraph.uni-bayreuth.de/showcase/infinity.html">Infinity</url>.
</p>
<p>
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, <ie /> a square.
</p>
<figure>
<caption>Infinity, from the JSXGraph Showcase</caption>
<interactive xml:id="interactive-infinity" platform="jsxgraph" width="60%" source="code/jsxgraph/infinity.js">
<slate xml:id="jsxgraph-infinity" surface="jsxboard" />
<instructions>
<p>
Drag the sliders to change the pattern,
and drag any of the four red corners to change the overall shape.
</p>
</instructions>
</interactive>
</figure>
<p>
Here are the two new examples.
They have been included in a <c>sidebyside</c> layout element with equal widths
(see <xref ref="section-side-by-side" text="type-global" />)
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
<url href="http://jsxgraph.uni-bayreuth.de/wiki/index.php/Category:Examples" visual="jsxgraph.uni-bayreuth.de/wiki/index.php/Category:Examples">JSXGraph example wiki</url>,
the left being Fermat's Spiral and the right being a demonstration of B-splines.
</p>
<sidebyside widths="40% 40%">
<interactive xml:id="interactive-fermats-spiral" platform="jsxgraph" source="code/jsxgraph/fermats-spiral.js">
<slate xml:id="jsxgraph-fermats-spiral" surface="jsxboard" />
<instructions>
<p>
Drag the slider to change the curve.
</p>
</instructions>
</interactive>
<interactive xml:id="interactive-bspline" platform="jsxgraph" source="code/jsxgraph/bspline.js">
<slate xml:id="jsxgraph-bspline" surface="jsxboard" />
<instructions>
<p>
Any of the 8 red control points may be moved anywhere.
</p>
</instructions>
</interactive>
</sidebyside>
<p>
Finally, a piecewise function you can control,
with traces of the domain values and range values in two other JSXGraph boards.
Boards and <init>HTML</init> buttons have been laid out using the <c>sidebyside</c> layout element.
</p>
<figure xml:id="figure-piecewise">
<caption>Piecewise Function</caption>
<interactive xml:id="interactive-piecewise" platform="jsxgraph" aspect="20:8" source="code/jsxgraph/piecewise.js">
<sbsgroup>
<sidebyside width="30%" margins="0%">
<slate xml:id="box_p3" surface="jsxboard" aspect="6:6" />
<slate xml:id="box2_p3" surface="jsxboard" aspect="6:6" />
<slate xml:id="box3_p3" surface="jsxboard" aspect="6:6" />
</sidebyside>
<sidebyside widths="30% 30%" margins="20%">
<slate surface="html">
<input xmlns="http://www.w3.org/1999/xhtml" type="button" value="Animate" onkeypress="animate_p3(s_p3,75,100);" onclick="animate_p3(s_p3,75,100);" style="font-size:16px; width:100%" />
</slate>
<slate surface="html">
<input xmlns="http://www.w3.org/1999/xhtml" type="button" value="Clear Traces" onkeypress="clearTraces_p3();" onclick="clearTraces_p3();" style="font-size:16px; width:100%" />
</slate>
</sidebyside>
</sbsgroup>
<instructions>
<p>
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.
</p>
</instructions>
</interactive>
</figure>
<p>
Generally, we load an interactive into an HTML <c>iframe</c> 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 <tag>slate</tag> need to communicate, then they are related,
and should be placed into a single <tag>interactive</tag>,
allowed to layout themselves,
or grouped within a <tag>sidebyside</tag> allowing finer control.
Even if we have this under control,
you might still enjoy reading
<url href="http://mikecavaliere.com/your-js-is-a-mess-javascript-namespacing/" visual="mikecavaliere.com/your-js-is-a-mess-javascript-namespacing/">Your JS is a Mess</url>
at <c>mikecavaliere.com/your-js-is-a-mess-javascript-namespacing/</c>.
</p>
</subsection>
<subsection>
<title>JessieCode</title>
<idx>JessieCode</idx>
<p>
<url href="https://jsxgraph.uni-bayreuth.de/wp/docs_jessiecode/" visual="jsxgraph.uni-bayreuth.de/wp/docs_jessiecode/">JessieCode</url>
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 <tag>div</tag> element as you would for any other JSXGraph interactive plot and then provide the JessieCode script,
which focuses on the geometric elements.
</p>
<p>
Because JessieCode is provided by JSXGraph,
the interactive platform is <c>jsxgraph</c>.
The <tag>slate</tag>, however,
uses <attr>surface</attr> with value <c>jessiecode</c>.
The script can be embedded directly in your code.
As usual, you would need to remember to escape the special characters.
JessieCode uses <c><</c> and <c>></c> for inequalities as well as for declaring objects used to style geometric elements,
and <c>&&</c> is the boolean AND operator.
Alternatively, you can provide the file as a separate resource,
providing the URL with a <attr>source</attr> attribute.
Attributes defining the JSXBoard at the time it is created should be included as attributes of the <tag>slate</tag>,
including <attr>boundingbox</attr>,
<attr>axis</attr>, and <attr>grid</attr>.
</p>
<p>
For this first example,
the JessieCode was included directly in the XML source as the contents of the associated slate.
</p>
<figure xml:id="figure-quadratic-slope">
<caption>Finding the Tangent Line of a Quadratic Function</caption>
<interactive xml:id="interactive-quadratic-tangent" platform="jsxgraph" width="80%">
<slate xml:id="quadratic-tangent-plot" surface="jessiecode" axis="true" grid="false">
a = slider([-4.5,4], [-1.5,4], [-2,1,2])
<<
name:"a",
snapWidth:0.25,
point1: << frozen: true >>,
point2: << frozen: true >>
>>;
b = slider([-4.5,3.5], [-1.5,3.5], [-4,-1,4])
<<
name:"b",
snapWidth:0.5,
point1: << frozen: true >>,
point2: << frozen: true >>
>>;
c = slider([-4.5,3], [-1.5,3], [-4,0,4])
<<
name:"c",
snapWidth:0.5,
point1: << frozen: true >>,
point2: << frozen: true >>
>>;
fGraph = functiongraph(function(x) {
return a.Value()*x^2 + b.Value()*x + c.Value();
});
P = glider(1,0, fGraph);
Q = point(2,2)
<< name:"P" >>;
secant = line(P,Q)
<< color: (function() {
m = (Q.Y() - P.Y())/(Q.X() - P.X());
dydx = 2*a.Value()*P.X() + b.Value();
cVal = "red";
if (abs(m-dydx) < 0.001) {
cVal = "blue";
}
return cVal;
})
>>;
dydxValue = text(-4, 1.5, function() {
m = 2*a.Value()*P.X() + b.Value();
return ("dy/dx = " + trunc(m,3));
})
<< frozen: true >>;
mValue = text(-4, 1, function() {
m = (Q.Y() - P.Y())/(Q.X() - P.X());
return ("m = " + trunc(m,3));
})
<< frozen: true >>;
</slate>
<instructions>
<p>
Use the sliders to set the parameters of the quadratic <m>f(x)=ax^2+bx+c</m>.
Drag the point <m>A</m> on the graph and the point <m>P</m> to define a line.
Try to make the line tangent at the point at <m>A</m> and observe the resulting slope of the tangent line.
</p>
</instructions>
</interactive>
</figure>
<p>
For this second example,
the JessieCode was included through an associated script file,
loaded by the browser.
</p>
<figure xml:id="figure-nondifferentiable-oscillation">
<caption>Graph of a function that is continuous but not differentiable at <m>x=0</m> because the slope of the secant line has no limit.</caption>
<interactive xml:id="interactive-oscillating-secant" platform="jsxgraph" width="90%">
<slate xml:id="graph-cts-not-diff-function" surface="jessiecode" source="code/jsxgraph/cts-not-diff-oscillate.jc" axis="true" />
<instructions>
<p>
Drag the point <m>B</m> to move the point on the graph and change the secant line.
Notice that there is no well-defined limiting tangent line as <m>x \to 0</m>.
</p>
</instructions>
</interactive>
</figure>
</subsection>
<subsection>
<title>Sage Interacts</title>
<idx><h>Sage</h><h>interacts</h></idx>
<p>
Sage, and the Sage Cell Server,
support interactive demonstrations,
called <term>interacts</term>.
<ul>
<li>
The interactive elements are nearly trivial to construct.
</li>
<li>
An interact is simply a single Python function
(acted on by a decorator).
</li>
<li>
You have the full mathematical power of Sage at your disposal,
so can do some very powerful computations with high precision
(or exactly).
</li>
<li>
The interface is not as polished as what you can achieve with Javascript libraries.
</li>
<li>
Graphics refresh with a round-trip to the server,
so are not nearly as fluid as with other tools.
</li>
</ul>
Note that each interact is insulated from the others,
unlike our other employment of the Sage Cell Server.
</p>
<p>
This example is by Marshall Hampton, taken from the
<url href="https://wiki.sagemath.org/interact/calculus" visual="wiki.sagemath.org/interact/calculus">Sage interact wiki</url>,
specifically
<url href="https://wiki.sagemath.org/interact/calculus#Numerical_integrals_with_the_midpoint_rule" visual="wiki.sagemath.org/interact/calculus#Numerical_integrals_with_the_midpoint_rule">Numerical integrals with the midpoint rule</url>.
</p>
<figure xml:id="figure-interactive-numerical-integral">
<caption>Numerical integrals using the midpoint rule</caption>
<interactive xml:id="interactive-numerical-integral" platform="sage" width="100%" aspect="4:5">
<slate surface="sage">
var('x')
@interact
def midpoint(n = slider(1,100,1,4), f = input_box(default = "x^2", type = str, width=40), start = input_box(default = "0", type = str, width=6), end = input_box(default = "1", type = str,width=6)):
a = N(start)
b = N(end)
func = sage_eval(f, locals={'x':x})
dx = (b-a)/n
midxs = [q*dx+dx/2 + a for q in range(n)]
midys = [func(x=x_val) for x_val in midxs]
rects = Graphics()
for q in range(n):
xm = midxs[q]
ym = midys[q]
rects = rects + line([[xm-dx/2,0],[xm-dx/2,ym],[xm+dx/2,ym],[xm+dx/2,0]], rgbcolor = (1,0,0)) + point((xm,ym), rgbcolor = (1,0,0))
min_y = min(0, find_local_minimum(func,a,b)[0])
max_y = max(0, find_local_maximum(func,a,b)[0])
pretty_print(html('<h3>Numerical integrals with the midpoint rule</h3>'))
pretty_print(html('$\\int_{a}^{b}{f(x) dx} {\\approx} \\sum_i{f(x_i) \\Delta x}$'))
print("\n\nSage numerical answer: " + str(integral_numerical(func,a,b,max_points = 200)[0]))
print("Midpoint estimated answer: " + str(RDF(dx*sum([midys[q] for q in range(n)]))))
show(plot(func,a,b) + rects, xmin = a, xmax = b, ymin = min_y, ymax = max_y,figsize=5)
</slate>
</interactive>
</figure>
</subsection>
<subsection>
<title>Geogebra</title>
<p>
To embed a GeoGebra applet as-is from GeoGebra's Classroom Resources site
(by material ID),
see <xref ref="subsection-geogebra-server" text="type-global" />.
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
<q>Apps</q>
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.
</p>
<p>
Do one of the following:
<ol>
<li>
Identify a material ID from GeoGebra's Classroom Resources site.
You might even make the material yourself on that site.
</li>
<li>
Obtain a <c>.ggb</c> 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 <c>.ggb</c> file,
you can decode the string and save the result.
For example,
at <url href="https://www.opinionatedgeek.com/codecs/base64decoder" />.
</li>
<li>
Obtain a base64 encoded string for a GeoGebra applet.
You might first open a <c>.ggb</c> 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.
</li>
<li>
None of the above, with the intention to make an applet from scratch.
</li>
</ol>
</p>
<p>
Then mimic the examples that follow,
using GeoGebra API commands documented at
<url href="https://wiki.geogebra.org/en/Reference:GeoGebra_Apps_API">Geogebra API Manual</url>,
but do not include the <c>ggbApplet.</c> or <c>applet.</c> used in examples to prefix the functions<mdash />that part of the code will be provided automatically by <pretext />.
</p>
<p>
Jack Green created an applet on the Classroom Resources site with ID <c>D4s2v4ft</c>,
which you may view at <url href="https://www.geogebra.org/m/D4s2v4ft" visual="www.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 <m>y</m>-axis ticks be separated <m>5</m> apart instead of <m>10</m> apart.
We also decide we want a different aspect ratio and overall width.
One gotcha: the original applet is loaded and then <pretext /> uses <attr>width</attr> and <attr>aspect</attr> 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
<url href="https://wiki.geogebra.org/en/Reference:GeoGebra_Apps_API" visual="wiki.geogebra.org/en/Reference:GeoGebra_Apps_API">Geogebra API Manual</url>.
It is important to use one command per line.
</p>
<figure>
<caption>GeoGebra: modified material ID</caption>
<interactive xml:id="geogebra-train-distance" platform="geogebra" width="75%" aspect="2:1">
<slate xml:id="train-distance" surface="geogebra" material="D4s2v4ft" aspect="2:1">
setAxisSteps(1, 1, 5, 1);
setCoordSystem(-0.7, 8, -6, 56);
enableShiftDragZoom(false);
</slate>
</interactive>
</figure>
<p>
The same can be done with a <c>.ggb</c> 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.
</p>
<figure>
<caption>GeoGebra: <c>.ggb</c> file</caption>
<interactive xml:id="geogebra-astroid-original" platform="geogebra" width="100%" aspect="4:3">
<slate xml:id="astroid-original" surface="geogebra" source="code/rosoff/astroid.ggb" aspect="4:3" />
</interactive>
</figure>
<p>
Now we modify David's applet in a few ways.
</p>
<figure>
<caption>GeoGebra: modified from <c>.ggb</c> file</caption>
<interactive xml:id="geogebra-astroid" platform="geogebra" width="100%" aspect="4:3">
<slate xml:id="astroid" surface="geogebra" source="code/rosoff/astroid.ggb" aspect="4:3">
setCoordSystem(-6, 10, -6, 6);
setLabelVisible("b", false);
setLabelVisible("c", false);
setLabelVisible("d", false);
setAxisLabels(1,"x","y","z");
evalCommand("r = Slider(1,4,0.1)");
showResetIcon(true);
</slate>
</interactive>
</figure>
<figure>
<caption>GeoGebra: modified from <c>.ggb</c> file</caption>
<interactive xml:id="geogebra-cycloid" platform="geogebra" width="100%" aspect="2:1">
<slate xml:id="cycloid" surface="geogebra" source="code/rosoff/epi-hypocycloids-default.ggb" aspect="2:1">
setCoordSystem(-15,5,-5,5);
setAnimating("θ", true);
</slate>
</interactive>
</figure>
<p>
In 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.
</p>
<figure>
<caption>GeoGebra: a constructive
<q>proof</q>
that SAS congruence holds in Euclidean geometry (from Tevian Dray)</caption>
<interactive xml:id="geogebra-SAS" platform="geogebra" width="100%" aspect="1:1">
<slate xml:id="SAS" surface="geogebra" source="code/dray/SAS.ggb" aspect="1:1" />
<instructions>
<p>
Drag some of the points and some of the circles to change them,
and watch the remainder react.
</p>
</instructions>
</interactive>
</figure>
<p>
You could also use a base64-encoded string of the <c>.ggb</c> file.
You might come across such a string somewhere,
or you might generate one by opening a <c>.ggb</c> 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 <attr>base64</attr> attribute in place of the <attr>source</attr> 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.
</p>
<p>
The next example shows how you can communicate between a GeoGebra applet and a <tag>slate</tag> contained in the interactive.
The process is mediated by javascript code specified in the <attr>source</attr> attribute of the interactive.
Event listeners in the code update the HTML when the diagram changes or vice-versa.
MathJax is also notified when it needs to update math.
</p>
<p>
Note that this example has a <tag>slate</tag> whose <attr>surface</attr> is <c>pretext</c> <em>and</em>
a <tag>slate</tag> whose <attr>surface</attr> is <c>html</c>,
the latter requiring a namespace declaration.
The former produces HTML according to the <pretext /> templates,
which is fairly predictable,
but never guaranteed to always be identical over time.
A <pretext /> slate uses familiar syntax,
produces results styled consistently,
but might break in the future.
While an HTML slate is similar,
the results will not be styled,
but it does allow for a wider range of HTML elements (a <c>button</c> element here) and will not change over time.
</p>
<p>
The indefinite integral in the last row of the table is a gratuitious test that aurhors' macros from <tag>docinfo</tag> are available to MathJax.
Finally, a <pretext /> slate will only recognize <tag>p</tag>,
<tag>tabular</tag>,
<tag>sidebyside</tag>, and <tag>sbsgroup</tag> as children.
Make a feature request if you have a good case for more.
</p>
<figure xml:id="figure_Interactive-3d-direction-vector">
<caption>Geogebra/<pretext /> Communications</caption>
<interactive platform="geogebra" aspect="10:8" width="100%" xml:id="ggb_3d-direction-vector_interactive" source="code/haynes/3d-direction-vector.js">
<slate xml:id="ggb_3d-direction-vector_slate" aspect="10:5" surface="geogebra" source="code/haynes/3d-direction-vector.ggb">
evalCommand("B2 = 3");
evalCommand("C2 = -1");
evalCommand("D2 = 2");
evalCommand("B3 = -1");
evalCommand("C3 = 4");
evalCommand("D3 = 1");
setValue("showAB",true);
setValue("showBA",false);
evalCommand("ZoomIn(-Z,-Z,-Z/2,Z,Z,Z/2)");
evalCommand("SetViewDirection((1,1,1/2))");
enableRightClick(false);
</slate>
<sidebyside width="35%" margins="10%">
<slate surface="pretext" label="ggb_2__17_table1">
<tabular halign="right">
<col width="10%" halign="center" />
<col width="10%" halign="center" />
<col width="10%" halign="center" />
<col width="10%" halign="center" />
<col width="30%" halign="right" />
<row bottom="minor">
<cell> <m>\ </m> </cell>
<cell> <m>x </m> </cell>
<cell> <m>y</m> </cell>
<cell> <m>z </m> </cell>
<cell />
</row>
<row>
<cell> <m>\mathbf{A}</m> </cell>
<cell />
<cell />
<cell />
<cell />
</row>
<row>
<cell> <m>\mathbf{B}</m> </cell>
<cell />
<cell />
<cell />
<cell />
</row>
<row>
<cell><m>\indefiniteintegral{x^4}{x}</m></cell>
<cell />
<cell />
<cell />
<cell />
</row>
</tabular>
</slate>
<slate surface="html">
<p xmlns="http://www.w3.org/1999/xhtml">
<button id="a_to_b">Show A to B</button>
<button id="b_to_a">Show B to A</button>
</p>
</slate>
</sidebyside>
<sidebyside>
<p label="info" />
</sidebyside>
<instructions>
<p>
This interactive shows <m>\vec{r}_{AB}</m>,
the displacement vector from <m>\vec{A}</m> to <m>\vec{B}</m> and the corresponding unit displacement vector <m>\lambda_{AB}</m>.
</p>
<p>
You may change <m>\vec{A}</m> and <m>\vec{B}</m> by moving the red and blue dots.
Click the dot to switch between <m>x</m>-<m>y</m> mode and <m>z</m> mode.
Coordinates of <m>\vec{A}</m> and <m>\vec{B}</m> can also be entered into the table directly.
</p>
</instructions>
</interactive>
</figure>
<p>
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 <c>setFixed</c> 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.
Note that the GeoGebra scripting command <c>setAttribute</c> also changes the webpage's focus,
so it is better to set the perspective using an attribute of the slate.
</p>
<figure>
<caption>GeoGebra: from scratch</caption>
<interactive xml:id="geogebra-seed-head" platform="geogebra" width="50%" aspect="1:1">
<slate xml:id="seed-head" surface="geogebra" aspect="1:1" perspective="G">
setRounding("3s");
setCoordSystem(-1,1,-1,1);
setGridVisible(false);
setAxesVisible(false, false);
evalCommand("f(x)=If(x>0,sqrt(x),0)");
setVisible("f", false);
evalCommand("T=20");
evalCommand("t=Slider(0,T)");
setAnimating("t", true);
evalCommand("v=Vector((cos(t),sin(t)))");
evalCommand("r=Slider(0,1)");
evalCommand("r=(sqrt(5)-1)/2");
evalCommand("r=Slider(0,1,0.001)");
evalCommand("N=Min(100,floor(T/r))");
evalCommand("Seeds = Sequence(f(t - n r) / sqrt(T) (cos(n r 2 pi), sin(n r 2 pi)), n, 0, N)");
setFixed("v", false, false);
setFixed("Seeds", false, false);
</slate>
</interactive>
</figure>
</subsection>
<subsection>
<title>CircuitJS</title>
<p>
<url href="https://www.falstad.com/circuit/" visual="www.falstad.com/circuit">CircuitJS</url>
is an electronic circuit simulator.
A circuit can be described by a language,
which PreTeXt will interpret and submit for rendering.
The next two examples are identical,
but provided in slightly different ways,
see the <pretext /> source for more.
Preview images for PDF will be added later.
</p>
<figure xml:id="figure-circuitjs-attribute">
<caption>CircuitJS Example (source via an encoded attribute)</caption>
<interactive xml:id="interactive-circuitjs-attribute" circuitjs="$ 1 0.000005 10.20027730826997 58 5 50 5e-11%0AR 464 32 464 -16 0 0 40 3.3 0 0 0.5%0Ag 464 224 464 240 0 0%0As 464 32 464 128 0 0 false%0As 464 128 464 224 0 1 false%0Ax 274 181 431 184 4 12 bottom\sswitch\s(to\sground)%0Ax 312 85 426 88 4 12 top\sswitch\s(to\sVdd)%0AO 464 128 544 128 1 0%0Ax 532 110 593 113 4 12 output\spin" width="90%" aspect="4:3" />
</figure>
<figure xml:id="figure-circuitjs">
<caption>CircuitJS Example (source authored directly)</caption>
<interactive xml:id="interactive-circuitjs" circuitjs="" width="90%">
<source>
$ 1 0.000005 10.20027730826997 58 5 50 5e-11
R 464 32 464 -16 0 0 40 3.3 0 0 0.5
g 464 224 464 240 0 0
s 464 32 464 128 0 0 false
s 464 128 464 224 0 1 false
x 274 181 431 184 4 12 bottom\sswitch\s(to\sground)
x 312 85 426 88 4 12 top\sswitch\s(to\sVdd)
O 464 128 544 128 1 0
x 532 110 593 113 4 12 output\spin
</source>
</interactive>
</figure>
</subsection>
<subsection xml:id="interactive-iframes-local">
<title>IFrames from Files</title>
<p>
An <c>iframe</c> is an <init>HTML</init> element that allows embedding of a complete web page within another one.
Here we use this device to provide interactive 3D diagrams built with other tools.
</p>
<p>
We begin with a Jupyter notebook hosted on <url href="https://cocalc.com" visual="CoCalc.com" />.
News of success on other hosts for Jupyter notebook servers will allow us to expand this description.
We use a Sage kernel and create a 3D surface suggested by Juan Carlos Bustamante:
<cd>
<cline>var('x,y')</cline>
<cline>plot3d(x^2 - y^2, (x,-1,1), (y,-1,1), color="orange", mesh=true)</cline>
</cd>
News of other computational engines that produce similar graphics will also allow us to further expand this description.
Note that for the case of Sage 3D plots,
support for the <tag>sageplot</tag> element makes this even easier.
For example, see <xref ref="figure-sage-implicit-surface" />.
</p>
<p>
A button in the lower right allows for several options,
one is <c>Save as HTML</c>,
which will produce a complete self-contained web page we can recycle.
We save this file with our other externally-created images,
in a directory that we choose to name <c>iframe</c><mdash />you can use another name.
Then we make an <tag>interactive</tag> with an <attr>iframe</attr> attribute that has the filename,
starting from <c>iframe/</c> (in other words,
do not include the name of your managed directory of external images).
</p>
<figure xml:id="figure-sage-jupyter-iframe">
<caption>Sage+Jupyter <c>iframe</c></caption>
<interactive xml:id="interactive-sage-jupyter-iframe" iframe="iframe/sage-jupyter.html" width="95%" aspect="1:1" />
</figure>
<p>
Note that the downloaded file has links to specific versions of the <c>three.js</c> library,
which are beyond our control, and beyond your control.
So there is a future where these images may need updating.
You could put your source code into a (large) comment with your project's source for safe-keeping in the future.
See <xref ref="interactive-iframes-server" text="type-global" /> for the server version.
</p>
</subsection>
<subsection xml:id="interactive-threejs">
<title>threejs</title>
<p>
Once upon a time there was an example here using the <c>threejs</c> 3D Javascript library.
It was
<url href="https://threejs.org/examples/#webgl_geometry_extrude_splines" visual="threejs.org/examples/#webgl_geometry_extrude_splines">one of the project's examples</url>,
licensed with an MIT License,
with minimal modifications.
</p>
<p>
But it would seem to have become a bit more complicated to embed and our example was not rendering.
As of 2022-08-08, we have removed it.
Of course, you can find it in the git repository,
perhaps searching on the date string just mentioned.
It woulld be interesting to see if our <tag>interactive</tag> framework could still support the changes.
</p>
<p>
The following two examples are meant to be instructive
(<em>only</em>).
The end result is accomplished in a much more straightforward way be the method in <xref ref="interactive-iframes-local" text="type-global" />.
We illustrate a way to get a <c>three.js</c> image out of an <init>HTML</init> page as a Javascript file and render it on a <pretext /> <tag>slate</tag>.
We follow the second method in a
<url href="https://golem.ph.utexas.edu/category/2017/12/sagemath_and_3d_models_in_webp.html" visual="golem.ph.utexas.edu/category/2017/12/sagemath_and_3d_models_in_webp.html">blog post from the <m>n</m>-Category Cafe</url>.
<ol>
<li>
Open a Jupyter Notebook that utilizes a Sage kernel.
This can be done easily at
<url href="https://cocalc.com" visual="cocalc.com">CoCalc</url>
(and for free initially).
</li>
<li>
Sketch a surface using Sage code.
We recycle the suggestion from Juan Carlos Bustamante in <xref ref="interactive-iframes-local" text="type-global" />:
<cd>
<cline>var('x,y')</cline>
<cline>plot3d(x^2 - y^2, (x,-1,1), (y,-1,1), color="orange", mesh=true)</cline>
</cd>
</li>
<li>
Look for a button
(in the lower-right)
which will provide a menu option <c>Save as HTML</c>.
Save the resulting <init>HTML</init> file,
and open a <em>copy</em> in a text editor.
</li>
<li>
<p>
You are now looking for two <init>HTML</init> <c>script</c> elements.
One will tell you just which version of <c>three.js</c> is being used,
vis a <c>@src</c> attribute.
For the second example below we located
<cd>
<cline>https://cdn.jsdelivr.net/gh/sagemath/threejs-sage@r122/build/three.min.js</cline>
</cd>
The <c>@r122</c> will likely be a version number,
which is a good thing for the longevity of your work.
This will get used in the <attr>source</attr> attribute of your <tag>interactive</tag>,
which will have <attr>platform</attr> set to <c>javascript</c>.
</p>
<p>
The second <c>script</c> element is likely huge and has many generic functions defined it.
There may be a huge variable full of data points computed by Sage.
Copy the <em>contents</em> of this <c>script</c> element into a new Javascript file
(so use a <c>.js</c> extension).
Do not edit in any way until you read further.
Once adjusted,
this file too gets specified in the <attr>source</attr> attribute of your <tag>interactive</tag>.
</p>
</li>
<li>
Your <tag>interactive</tag> needs a <tag>slate</tag> element for the graphic to draw on,
and you will need to give it a proper <attr>xml:id</attr> attribute,
plus teh <attr>surface</attr> will be set to <c>div</c>.
Then you need to edit the Javascript file to connect the graphic with the slate,
via IDs in your <pretext /> source and on teh <init>HTML</init> <c>div</c> created by the slate.
Look at the provided examples to see how.
Do not make any other edits to this file, even if tempted.
</li>
<li>
Study the two examples below,
and mimic how they were constructed.
</li>
</ol>
</p>
<p>
First, the example given in the blog post referenced above.
</p>
<figure xml:id="figure-threejs-catenoid-surface">
<caption><c>threejs</c> catenoid surface, from <m>n</m>-Category Cafe</caption>
<interactive xml:id="interactive-threejs-catenoid-surface" platform="javascript" width="75%" aspect="2:1" source="https://cdn.rawgit.com/mrdoob/three.js/r80/build/three.min.js https://cdn.rawgit.com/mrdoob/three.js/r80/examples/js/controls/OrbitControls.js code/threejs/catenoid.js">
<slate xml:id="threejs-catenoid-surface" surface="div" aspect="2:1" />
</interactive>
</figure>
<p>
Second, the example from JC Bustamante.
</p>
<figure xml:id="figure-threejs-saddle">
<caption><c>threejs</c> saddle by Sage</caption>
<interactive xml:id="interactive-threejs-saddle" platform="javascript" width="85%" aspect="1:1" source="https://cdn.jsdelivr.net/gh/sagemath/threejs-sage@r122/build/three.min.js code/threejs/saddle.js">
<slate xml:id="threejs-saddle" surface="div" aspect="1:1" />
</interactive>
</figure>
</subsection>
<subsection xml:id="interactive-doenetml">
<title>DoenetML</title>
<p>
<url href="https://doenet.org">DoenetML</url>
is a markup language inspired by <pretext /> for semantically describing interactive mathematics applets for the web.
Use <c>interactive[@platform="doenetml"]</c> with a <c>slate[@surface="doenetml"]</c> to include DoenetML content within your document.
</p>
<p>
Since DoenetML is similar to,
but not completely compatible with, XML, it cannot be authored directly within a PreTeXt document without painstakingly escaping every <c><</c> as <c>&lt;</c> and every <c>&</c> as <c>&amp;</c>.
However, a convenient workflow to avoid this is to author your DoenetML in a separate file like <c>example.doenetml</c>,
then include this file within your <pretext /> document using <c><xi:include parse="text" href="path/to/example.doenetml"/></c>.
</p>
<figure xml:id="figure-doenetml">
<caption>DoenetML example</caption>
<interactive label="interactive-doenetml-example" platform="doenetml" width="100%" aspect="3:2">
<slate surface="doenetml">
<p>
Adjust the vectors <m>\vec u</m>, <m>\vec v</m>, and <m>\vec w</m> in the
left graph to visualize the areas calculated by
<m>\det[\vec u\hspace{0.5em}\vec w]</m>, <m>\det[\vec v\hspace{0.5em}\vec w]</m>,
and
<m>\det[\vec u+\vec v\hspace{0.5em}\vec w]</m>.
</p>
<setup><line through="(0,0) $v" name="vLine"/><math simplify name="c">$cv.x/$v.x</math></setup>
<sideBySide>
<graph xmin="-4" ymin="-4" xmax="16" ymax="16">
<m draggable="false" anchor="(10,14)">
\det[\vec u\hspace{0.5em}\vec w],
\det[\vec v\hspace{0.5em}\vec w]
</m>
<point name="u" styleNumber="3">
(6,2)
<label><m>\vec u</m></label>
</point>
<point name="w" styleNumber="3">
(3,7)
<label><m>\vec w</m></label>
</point>
<point name="uPlusV" styleNumber="4">
(9,5)
<label><m>\vec v</m></label>
</point>
<polygon vertices="(0,0) $u $u+$w $w" filled draggable="false" styleNumber="3"/>
<polygon vertices="$u $uPlusV $uPlusV+$w $u+$w" filled draggable="false" styleNumber="4"/>
<lineSegment endpoints="(0,0) $uPlusV" styleNumber="6"/>
<lineSegment endpoints="$w $uPlusV+$w" styleNumber="6"/>
</graph>
<graph xmin="-4" ymin="-4" xmax="16" ymax="16">
<m draggable="false" anchor="(12,14)">
\det[\vec u+\vec v\hspace{0.5em}\vec w]
</m>
<polygon vertices="(0,0) $uPlusV $uPlusV+$w $w" filled draggable="false" styleNumber="2"/>
<point draggable="false" styleNumber="3">
$w
<label><m>\vec w</m></label>
</point>
<point draggable="false" styleNumber="4">
$uPlusV
<label><m>\vec u+\vec v</m></label>
</point>
<lineSegment endpoints="(0,0) $u" styleNumber="6"/>
<lineSegment endpoints="$u $uPlusV" styleNumber="6"/>
<lineSegment endpoints="$w $w+$u" styleNumber="6"/>
<lineSegment endpoints="$w+$u $w+$uPlusV" styleNumber="6"/>
</graph>
</sideBySide>
</slate>
</interactive>
</figure>
</subsection>
</section>
Section 13 Interactive Elements, Authored in Javascript
View Source for section
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 14 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 13.1 HTML5 Canvas
View Source for subsection
<subsection xml:id="interactive-html5-canvas">
<title>HTML5 Canvas</title>
<p>
<init>HTML5</init> introduced the <tag>canvas</tag> element,
which can be thought of a blank slate,
a place to draw or write on.
So <pretext /> has the <tag>slate</tag> element for a similar purpose.
Generally, but not exclusively,
<init>HTML5</init> writes on a <tag>canvas</tag> using the Javascript language.
We demonstrate this approach to interactive diagrams in this subsection.
</p>
<p>
The following examples are from David Austin's excellent
<url href="http://merganser.math.gvsu.edu/david/linear.algebra/ula/index.html" visual="merganser.math.gvsu.edu/david/linear.algebra/ula/index.html">
<pubtitle>Understanding Linear Algebra</pubtitle></url>
textbook, which can be found at
<cd>
<cline>merganser.math.gvsu.edu/david/linear.algebra/ula/index.html</cline>
</cd>
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.
</p>
<figure xml:id="figure-simple-eigenvector">
<caption>A simple eigenvector demonstration</caption>
<interactive xml:id="interactive-simple-eigenvector" platform="javascript" width="60%" source="code/austin/figures.js code/austin/simple-ev.js" preview="preview/simple-eigenvector-preview.jpg">
<slate xml:id="eigenvector" surface="canvas" />
<instructions>
<p>
Let <m>\vec{x}</m> be represented by the red arrow,
and <m>A\vec{x}</m> by the grey arrow,
for some particular <m>2\times 2</m> matrix <m>A</m>.
Drag the <em>tip</em> of the red arrow to see the grey arrow change.
</p>
</instructions>
</interactive>
</figure>
<exercise>
<p>
The interactive in <xref ref="figure-simple-eigenvector" text="type-global" /> shows a vector <m>\vec{x}</m> in red,
and the matrix-vector product <m>A\vec{x}</m> in grey,
for a particular <m>2\times 2</m> matrix <m>A</m>.
The four entries of the matrix <m>A</m> are coded into the interactive.
Can you deduce <m>A</m> simply by using the interactive?
Which theorem is the key?
</p>
</exercise>
<figure xml:id="figure-eigenvectors">
<caption>Eigenvector demonstration</caption>
<interactive xml:id="interactive-eigenvectors" platform="javascript" width="90%" aspect="4:5" source="code/austin/figures.js code/austin/eigenvectors.js" preview="preview/eigenvectors-preview.jpg">
<slate xml:id="sliders" aspect="4:1" surface="canvas" />
<slate xml:id="eigenvectors" aspect="4:4" surface="canvas" />
<instructions>
<p>
Let <m>\vec{x}</m> be represented by the red arrow,
and <m>A\vec{x}</m> by the grey arrow,
for a <m>2\times 2</m> matrix <m>A</m>.
Drag the <em>tip</em> 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 <m>2\times 2</m> matrix <m>A</m>.
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?
</p>
</instructions>
</interactive>
</figure>
<p>
The next example has ten <tag>slate</tag> elements communicating with each other,
and arranged with the layout features of a <tag>sidebyside</tag>
(see <xref ref="section-side-by-side" text="type-global" />).
</p>
<figure xml:id="figure-animation">
<caption>Affine Transformations</caption>
<interactive xml:id="interactive-animation" platform="javascript" width="100%" aspect="12:10" source="code/austin/animation.js" preview="preview/animation-preview.jpg">
<sbsgroup>
<sidebyside>
<slate xml:id="a" surface="canvas" aspect="4:1" />
<slate xml:id="b" surface="canvas" aspect="4:1" />
<slate xml:id="c" surface="canvas" aspect="4:1" />
</sidebyside>
<sidebyside>
<slate xml:id="d" surface="canvas" aspect="4:1" />
<slate xml:id="e" surface="canvas" aspect="4:1" />
<slate xml:id="f" surface="canvas" aspect="4:1" />
</sidebyside>
<sidebyside>
<slate xml:id="left" surface="canvas" aspect="6:6" />
<slate xml:id="right" surface="canvas" aspect="6:6" />
</sidebyside>
<sidebyside width="25%" margins="25% 25%">
<slate surface="html" aspect="3:1">
<button xmlns="http://www.w3.org/1999/xhtml" type="button" id="compose">Compose</button>
</slate>
<slate surface="html" aspect="3:1">
<button xmlns="http://www.w3.org/1999/xhtml" type="button" id="reset">Reset</button>
</slate>
</sidebyside>
</sbsgroup>
<instructions>
<title>Flipping Woody</title>
<p>
Parameters <m>a</m>, <m>b</m>,
<m>d</m>, and <m>e</m>, form a <m>2\times 2</m> matrix <m>A</m>,
while <m>c</m> and <m>f</m> form a vector <m>\vec{b}</m>.
The two views of Woody shows the effect of the mapping
<me>
\vec{x}\mapsto A\vec{x} + \vec{b}
</me>.
</p>
</instructions>
</interactive>
</figure>
<warning>
<p>
If your <tag>interactive</tag> employs a <tag>slate</tag> with a <attr>surface</attr> attribute whose value is <c>html</c>,
then you are advised to augment each top-level (<init>HTML</init>) element within the <tag>slate</tag> with the attribute:
<cd>
<cline>xmlns="http://www.w3.org/1999/xhtml"</cline>
</cd>
This will identify <em>all</em>
of the elements within the <tag>slate</tag> as <init>HTML</init> elements and not as <pretext /> elements.
The danger is that elements with the same name in both languages,
such as <tag>li</tag> and <tag>table</tag>, will be mis-identified.
This could be harmless, but could also create chaos,
such as disrupting numbering of <pretext /> elements.
</p>
<p>
See the source code of this document for examples:
<xref ref="figure-animation" text="type-global" /> <xref ref="figure-interactive-slopes" text="type-global" />, <xref ref="figure-piecewise" text="type-global" />.
</p>
<p>
Note that the <init>HTML</init> 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.
</p>
</warning>
<p>
It is also possible to add <tag>script</tag> elements within an interactive that contain properly escaped JS code.
These elements will be placed at the end of the document created to hold the interactive content and can interactive with the other elements within the interactive but can not directly interact with the surrounding page.
</p>
<p>
Authors are strongly discouraged from trying to incorporate complex code in the form of a <tag>script</tag>,
but it can be a useful tool to call more complex code that is linked via <attr>source</attr> on the <tag>interactive</tag>.
</p>
<p>
This example uses a <tag>script</tag> to draw
<q>Hello World</q>
to a <tag>slate</tag>
</p>
<figure xml:id="figure-simple-js-script">
<caption>A simple embedded script example</caption>
<interactive aspect="6:1" xml:id="interactive-simple-js-script" platform="javascript" source="code/roesler/kinematics.js">
<slate aspect="6:1" xml:id="simple-js-script" surface="canvas" />
<script>
const canvas = document.getElementById("simple-js-script");
const ctx = canvas.getContext("2d");
ctx.font = "40px sans-serif";
ctx.fillText("Hello world", 10, 50);
</script>
</interactive>
</figure>
</subsection>
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
1
merganser.math.gvsu.edu/david/linear.algebra/ula/index.html
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.
Checkpoint 13.2.
View Source for exercise
<exercise>
<p>
The interactive in <xref ref="figure-simple-eigenvector" text="type-global" /> shows a vector <m>\vec{x}</m> in red,
and the matrix-vector product <m>A\vec{x}</m> in grey,
for a particular <m>2\times 2</m> matrix <m>A</m>.
The four entries of the matrix <m>A</m> are coded into the interactive.
Can you deduce <m>A</m> simply by using the interactive?
Which theorem is the key?
</p>
</exercise>
The interactive in Figure 13.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?
The next example has ten
<slate>
elements communicating with each other, and arranged with the layout features of a <sidebyside>
(see Section 25).Warning 13.5.
View Source for warning
<warning>
<p>
If your <tag>interactive</tag> employs a <tag>slate</tag> with a <attr>surface</attr> attribute whose value is <c>html</c>,
then you are advised to augment each top-level (<init>HTML</init>) element within the <tag>slate</tag> with the attribute:
<cd>
<cline>xmlns="http://www.w3.org/1999/xhtml"</cline>
</cd>
This will identify <em>all</em>
of the elements within the <tag>slate</tag> as <init>HTML</init> elements and not as <pretext /> elements.
The danger is that elements with the same name in both languages,
such as <tag>li</tag> and <tag>table</tag>, will be mis-identified.
This could be harmless, but could also create chaos,
such as disrupting numbering of <pretext /> elements.
</p>
<p>
See the source code of this document for examples:
<xref ref="figure-animation" text="type-global" /> <xref ref="figure-interactive-slopes" text="type-global" />, <xref ref="figure-piecewise" text="type-global" />.
</p>
<p>
Note that the <init>HTML</init> 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.
</p>
</warning>
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.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.
It is also possible to add
<script>
elements within an interactive that contain properly escaped JS code. These elements will be placed at the end of the document created to hold the interactive content and can interactive with the other elements within the interactive but can not directly interact with the surrounding page.Authors are strongly discouraged from trying to incorporate complex code in the form of a
<script>
, but it can be a useful tool to call more complex code that is linked via @source
on the <interactive>
.This example uses a
<script>
to draw “Hello World” to a <slate>
Subsection 13.2 D3.js
View Source for subsection
<subsection>
<title>D3.js</title>
<idx>D3.js</idx>
<p>
<term>D3</term> is a Javascript library for
<q>Data-Driven Documents</q>, which might greatly enhance some data you wish to display.
In short, it uses the animation capabilities of <init>SVG</init>.
Available examples seem sensitive to the version of the library,
so we have examples using different versions.
Use the <attr>version</attr> attribute on <tag>interactive</tag> to specify the version number.
The default is <c>5</c>.
</p>
<p>
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?
</p>
<p>
This is adapted from a
<url href="https://bl.ocks.org/mbostock/3231298" visual="bl.ocks.org/mbostock/3231298">block</url>
by
<url href="https://bl.ocks.org/mbostock" visual="bl.ocks.org/mbostock">Mike Bostock</url>
with a <init>GPL</init> license.
A similar demonstration,
only using an <init>HTML5</init> canvas is at <url href="https://bl.ocks.org/mbostock/3231307" visual="bl.ocks.org/mbostock/3231307" />.
</p>
<figure>
<caption>Force layout and collision detection</caption>
<interactive xml:id="interactive-d3-collision" platform="d3" version="3" width="80%" aspect="1:1" source="code/d3/collision.js" preview="preview/collision-preview.png">
<slate xml:id="d3-collision" surface="div" aspect="1:1" />
<instructions>
<p>
Place your mouse/pointer at the center of the interactive to repel the 200 circles.
</p>
</instructions>
</interactive>
</figure>
<p>
Similar, but different,
this demonstration of a graph layout uses Version 4 of the library.
Technical notes:
<ul>
<li>
We have changed the size of the nodes,
and their number, to fit in a smaller space.
</li>
<li>
The Javascript script uses introspection to size itself,
which would be a good general practice.
</li>
</ul>
</p>
<p>
This is adapted from a
<url href="https://bl.ocks.org/shimizu/e6209de87cdddde38dadbb746feaf3a3" visual="bl.ocks.org/shimizu/e6209de87cdddde38dadbb746feaf3a3">block</url>
by
<url href="https://bl.ocks.org/shimizu" visual="bl.ocks.org/shimizu">shimizu</url>
with a <init>GPL</init> license.
</p>
<figure>
<caption>Graph Layout</caption>
<interactive xml:id="interactive-d3-graph-layout" platform="d3" version="4" width="60%" aspect="1:1" source="code/d3/graph-layout.js" preview="preview/graph-layout-preview.png">
<slate xml:id="d3-graph-layout" surface="div" aspect="1:1" />
<instructions>
<p>
Drag a vertex to a new location to see the graph adjust its layout.
</p>
</instructions>
</interactive>
</figure>
<exercise>
<title>Graph Planarity</title>
<statement>
<p>
Can you move the vertices to new locations such that the resulting graph is planar? (In other words,
no edges cross?)
</p>
</statement>
</exercise>
<p>
Finally an example that actually uses some data.
Here is the description from the
<url href="https://bl.ocks.org/martinjc/7aa53c7bf3e411238ac8aef280bd6581" visual="bl.ocks.org/martinjc/7aa53c7bf3e411238ac8aef280bd6581">original block</url>
by
<url href="https://bl.ocks.org/martinjc" visual="bl.ocks.org/martinjc">Martin Chorley</url>
with an MIT License.
</p>
<blockquote>
<p>
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.
</p>
<p>
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.
</p>
<p>
Hover over the nodes to fade out non-connected nodes.
</p>
<p>
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.
</p>
</blockquote>
<p>
Technical notes:
<ul>
<li>
Once the nodes organize themselves
(automatically in the beginning),
they cannot be moved.
</li>
<li>
We have adjusted the margins in an attempt to keep names visible on the right side,
but without giving up too much space.
</li>
<li>
We have adjust the repelling force,
and the collision buffer, to better fit the available space.
</li>
<li>
This example required its own <init>CSS</init>,
which we have included as part of the <tag>interactive</tag>.
</li>
<li>
The data collected from the Twitter analysis is contained in a <init>JSON</init> file,
<c>mention_network.json</c>,
and where the script loads that file,
it has a hardcoded path.
So this example is a bit brittle, should that file move.
</li>
</ul>
</p>
<figure>
<caption>Tweet mentions within the Welsh Assembly</caption>
<interactive xml:id="interactive-d3-welsh" platform="d3" version="4" width="100%" aspect="1:2" source="code/d3/welsh.js" css="code/d3/welsh.css" preview="preview/welsh-assembly-preview.png">
<slate xml:id="d3-welsh" surface="div" aspect="1:2" />
<instructions>
<p>
Hover on the name of an Assembly Member to concentrate on their tweet mentions.
</p>
</instructions>
</interactive>
</figure>
</subsection>
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 with a GPL license. A similar demonstration, only using an HTML5 canvas is at
2
bl.ocks.org/mbostock/3231298
3
bl.ocks.org/mbostock
bl.ocks.org/mbostock/3231307
.Similar, but different, this demonstration of a graph layout uses Version 4 of the library. Technical notes:
This is adapted from a block by shimizu with a GPL license.
4
bl.ocks.org/shimizu/e6209de87cdddde38dadbb746feaf3a3
5
bl.ocks.org/shimizu
Finally an example that actually uses some data. Here is the description from the original block by Martin Chorley with an MIT License.
6
bl.ocks.org/martinjc/7aa53c7bf3e411238ac8aef280bd6581
7
bl.ocks.org/martinjc
View Source for blockquote
<blockquote> <p> 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. </p> <p> 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. </p> <p> Hover over the nodes to fade out non-connected nodes. </p> <p> 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. </p> </blockquote>
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:
Subsection 13.3 SVG
View Source for subsection
<subsection xml:id="svg-interactives">
<title>SVG</title>
<p>
Entirely similar to using an HTML5 <c>canvas</c> element
(<xref ref="interactive-html5-canvas" />),
it is possible to control an <init>SVG</init> element with Javascript.
This example is from Mark McClure.
</p>
<p>
Look carefully at the source and rendering of this example as <init>HTML</init>.
The functions to choose from via radio buttons,
and the change in <m>x</m>, denoted later as <m>h</m>,
are being rendered as mathematics by the Javascript MathJax library.
However, this cannot be accomplished with simply <c>$...$</c> nor by simply <c>\(...\)</c>,
but instead by using the <c>\(...\)</c> and then also wrapping that in a <tag>span</tag> element with a <attr>class</attr> attribute set to <c>process-math</c>. (The latter is how we instruct MathJax as to which parts of a page to process, or not).
So to have MathJax render a nice <m>x^2</m> in this context
(math inside <init>HTML</init> inside a <tag>slate</tag> inside an <tag>interactive</tag>)
would be accomplished with
<cd>
<cline><span class="process-math">x^2</span></cline>
</cd>
</p>
<figure xml:id="figure-interactive-slopes">
<caption>Tangent and secant slopes</caption>
<interactive xml:id="interactive-slopes" platform="javascript" width="100%" aspect="6:8" source="https://code.jquery.com/jquery-1.11.3.min.js https://d3js.org/d3.v3.min.js https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.2.1/math.min.js code/mcclure/slope.js" css="code/mcclure/slope.css">
<slate xml:id="function-list" surface="html" aspect="6:2">
<div xmlns="http://www.w3.org/1999/xhtml" class="p">
Calculus consists of those problems in mathematics that can be solved with the
following basic approach:
</div>
<div xmlns="http://www.w3.org/1999/xhtml" class="em_display">
Approximate and take a limit!
</div>
<div xmlns="http://www.w3.org/1999/xhtml" class="p">
The simplest, standard, geometric example of this process is the approximation
of the slope of a tangent line with a secant line.
Here's an illustration of this basic idea.
</div>
<div xmlns="http://www.w3.org/1999/xhtml" id="function_list" style="text-align: center">
Choose <span class="process-math">\(f\)</span>:
<span class="function_radio_container" style="padding-left: 10px">
<input type="radio" class="radio" name="function" value="f1" id="f1" />
<span class="process-math">\(f(x)=x^2\)</span>
</span>
<span class="function_radio_container">
<input type="radio" class="radio" name="function" value="f2" />
<span class="process-math">\(f(x)=\frac{1}{3}e^x\)</span>
</span>
<span class="function_radio_container">
<input type="radio" class="radio" name="function" value="f3" />
<span class="process-math">\(f(x)=\sin(2x^2)+x/4\)</span>
</span>
</div>
</slate>
<slate xml:id="the_graph" surface="svg" aspect="6:4" />
<slate xml:id="info-container" surface="html" aspect="6:2">
<div xmlns="http://www.w3.org/1999/xhtml" id="h_info_container">
<table>
<tr>
<td><table>
<tr><td><input id="show_secant_checkbox" type="checkbox" /> Show secant line</td></tr>
<tr><td><input id="h_slider" type="range" min="-0.5" max="0.5" step="0.01" /></td></tr>
</table></td>
<td><table>
<tr><td class="dimit" style="text-align: left;"><span class="process-math">\(h\)</span> = <span id="h_value_display" /></td></tr>
<tr><td class="dimit" style="text-align: left;">secant slope = <span id="secant_value_display" /></td></tr>
<tr><td style="text-align: left;">tangent slope = <span id="tangent_value_display" /></td></tr>
</table></td>
</tr>
</table>
</div>
</slate>
<instructions>
<p>
Select a function with the radio buttons,
then use the checkbox to add the secant line.
The denominator of the difference quotient, <m>h</m>,
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.
</p>
</instructions>
</interactive>
</figure>
<exercise>
<title>Changing Secant Lines</title>
<statement>
<p>
When discussing the derivative as a limit,
we think of the point of tangency as being fixed
(the green point in <xref ref="figure-interactive-slopes" />)
and the
<q>other</q>
point defining the secant line as changing
(the red point in <xref ref="figure-interactive-slopes" />).
Switch it up!
Fix a large value of <m>h</m>
(positive or negative)
and then change the point of tangency
(the green point).
Discuss what you observe.
</p>
</statement>
</exercise>
</subsection>
Entirely similar to using an HTML5
canvas
element (13.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 functions to choose from via radio buttons, and the change in \(x\text{,}\) denoted later as \(h\text{,}\) are being rendered as mathematics by the Javascript MathJax library. However, this cannot be accomplished with simply
$...$
nor by simply \(...\)
, but instead by using the \(...\)
and then also wrapping that in a <span>
element with a @class
attribute set to process-math
. (The latter is how we instruct MathJax as to which parts of a page to process, or not). So to have MathJax render a nice \(x^2\) in this context (math inside HTML inside a <slate>
inside an <interactive>
) would be accomplished with<span class="process-math">x^2</span>
Checkpoint 13.12. Changing Secant Lines.
View Source for exercise
<exercise>
<title>Changing Secant Lines</title>
<statement>
<p>
When discussing the derivative as a limit,
we think of the point of tangency as being fixed
(the green point in <xref ref="figure-interactive-slopes" />)
and the
<q>other</q>
point defining the secant line as changing
(the red point in <xref ref="figure-interactive-slopes" />).
Switch it up!
Fix a large value of <m>h</m>
(positive or negative)
and then change the point of tangency
(the green point).
Discuss what you observe.
</p>
</statement>
</exercise>
When discussing the derivative as a limit, we think of the point of tangency as being fixed (the green point in 13.11) and the “other” point defining the secant line as changing (the red point in 13.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 13.4 JSXGraph
View Source for subsection
<subsection>
<title>JSXGraph</title>
<idx>JSXGraph</idx>
<p>
<url href="http://jsxgraph.uni-bayreuth.de/wp/index.html" visual="jsxgraph.uni-bayreuth.de">JSXGraph</url>
is a
<q>cross-browser JavaScript library for interactive geometry,
function plotting,
charting, and data visualization in the web browser.</q>
Now a <tag>slate</tag> will be what JSXGraph calls a <term>board</term>.
Again, you use Javascript to write onto a <tag>slate</tag>,
but have some powerful shortcuts available from the JSXGraph library.
For this reason, <pretext /> calls JSXGraph a
<q>language</q>, 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.
</p>
<p>
Place Javascript inside a file that is specified with the <attr>source</attr> attribute of the <tag>interactive</tag> element.
Then just be certain that <attr>xml:id</attr> of the <tag>interactive</tag> element is passed as the <init>HTML</init> <c>id</c> in an (early) call to JSXGraph's <c>initBoard()</c> method.
</p>
<p>
The following example was contributed by Rick Roesler.
The <tag>figure</tag> is comprised of four <tag>stack</tag> elements within a <tag>sidebyside</tag>.
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.
</p>
<figure>
<caption>1-Dimensional Kinematics</caption>
<interactive xml:id="kinematics" platform="jsxgraph" aspect="6:7" source="code/roesler/kinematics.js">
<sidebyside width="70%" margins="15%">
<stack>
<slate xml:id="box_t" surface="jsxboard" aspect="6:1" />
<slate xml:id="box_s" surface="jsxboard" aspect="6:3" />
<slate xml:id="box_v" surface="jsxboard" aspect="6:3" />
<slate xml:id="box_a" surface="jsxboard" aspect="6:3" />
</stack>
</sidebyside>
<instructions xml:id="kinematics-instructions">
<p>
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.
</p>
</instructions>
<static>
<image source="images/kinematics.png" width="60%" />
</static>
</interactive>
</figure>
<p>
The plot below is the curve
<m>r=a+b\theta</m> in polar coordinates,
for <m>0\leq\theta\leq 8\pi</m>.
It may be manipulated with the sliders to control the shape of the curve.
Point <m>A</m> is contrained to the curve,
but may be dragged to a new location.
At <m>A</m> 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
<url href="http://jsxgraph.uni-bayreuth.de/wiki/index.php/Archimedean_spiral" visual="jsxgraph.uni-bayreuth.de/wiki/index.php/Archimedean_spiral">Archimedean Spiral</url>
is taken from the
<url href="http://jsxgraph.uni-bayreuth.de/wiki/index.php/Category:Examples" visual="jsxgraph.uni-bayreuth.de/wiki/index.php/Category:Examples">JSXGraph example wiki</url>.
The code could be written in 7 lines.
Width is 80% and aspect ratio is 4:3.
</p>
<figure>
<caption>The Archimedian Spiral <m>r = a + b\theta</m>, <m>0\leq\theta\leq 8\pi</m></caption>
<idx>Archimedian Spiral</idx>
<interactive xml:id="interactive-archimedian-spiral" platform="jsxgraph" width="80%" aspect="4:3" source="code/jsxgraph/archimedian.js">
<slate xml:id="jsxgraph-archimedian-spiral" surface="jsxboard" aspect="4:3" />
<instructions>
<p>
Drag the sliders to change the parameters <m>a</m> and <m>b</m>.
Controls in the lower-right will adjust the viewing window.
</p>
</instructions>
</interactive>
</figure>
<p>
Here is a more elaborate example, from the
<url href="http://jsxgraph.uni-bayreuth.de/showcase/" visual="jsxgraph.uni-bayreuth.de/showcase/">JSXGraph Showcase</url>,
titled
<url href="http://jsxgraph.uni-bayreuth.de/showcase/infinity.html" visual="jsxgraph.uni-bayreuth.de/showcase/infinity.html">Infinity</url>.
</p>
<p>
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, <ie /> a square.
</p>
<figure>
<caption>Infinity, from the JSXGraph Showcase</caption>
<interactive xml:id="interactive-infinity" platform="jsxgraph" width="60%" source="code/jsxgraph/infinity.js">
<slate xml:id="jsxgraph-infinity" surface="jsxboard" />
<instructions>
<p>
Drag the sliders to change the pattern,
and drag any of the four red corners to change the overall shape.
</p>
</instructions>
</interactive>
</figure>
<p>
Here are the two new examples.
They have been included in a <c>sidebyside</c> layout element with equal widths
(see <xref ref="section-side-by-side" text="type-global" />)
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
<url href="http://jsxgraph.uni-bayreuth.de/wiki/index.php/Category:Examples" visual="jsxgraph.uni-bayreuth.de/wiki/index.php/Category:Examples">JSXGraph example wiki</url>,
the left being Fermat's Spiral and the right being a demonstration of B-splines.
</p>
<sidebyside widths="40% 40%">
<interactive xml:id="interactive-fermats-spiral" platform="jsxgraph" source="code/jsxgraph/fermats-spiral.js">
<slate xml:id="jsxgraph-fermats-spiral" surface="jsxboard" />
<instructions>
<p>
Drag the slider to change the curve.
</p>
</instructions>
</interactive>
<interactive xml:id="interactive-bspline" platform="jsxgraph" source="code/jsxgraph/bspline.js">
<slate xml:id="jsxgraph-bspline" surface="jsxboard" />
<instructions>
<p>
Any of the 8 red control points may be moved anywhere.
</p>
</instructions>
</interactive>
</sidebyside>
<p>
Finally, a piecewise function you can control,
with traces of the domain values and range values in two other JSXGraph boards.
Boards and <init>HTML</init> buttons have been laid out using the <c>sidebyside</c> layout element.
</p>
<figure xml:id="figure-piecewise">
<caption>Piecewise Function</caption>
<interactive xml:id="interactive-piecewise" platform="jsxgraph" aspect="20:8" source="code/jsxgraph/piecewise.js">
<sbsgroup>
<sidebyside width="30%" margins="0%">
<slate xml:id="box_p3" surface="jsxboard" aspect="6:6" />
<slate xml:id="box2_p3" surface="jsxboard" aspect="6:6" />
<slate xml:id="box3_p3" surface="jsxboard" aspect="6:6" />
</sidebyside>
<sidebyside widths="30% 30%" margins="20%">
<slate surface="html">
<input xmlns="http://www.w3.org/1999/xhtml" type="button" value="Animate" onkeypress="animate_p3(s_p3,75,100);" onclick="animate_p3(s_p3,75,100);" style="font-size:16px; width:100%" />
</slate>
<slate surface="html">
<input xmlns="http://www.w3.org/1999/xhtml" type="button" value="Clear Traces" onkeypress="clearTraces_p3();" onclick="clearTraces_p3();" style="font-size:16px; width:100%" />
</slate>
</sidebyside>
</sbsgroup>
<instructions>
<p>
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.
</p>
</instructions>
</interactive>
</figure>
<p>
Generally, we load an interactive into an HTML <c>iframe</c> 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 <tag>slate</tag> need to communicate, then they are related,
and should be placed into a single <tag>interactive</tag>,
allowed to layout themselves,
or grouped within a <tag>sidebyside</tag> allowing finer control.
Even if we have this under control,
you might still enjoy reading
<url href="http://mikecavaliere.com/your-js-is-a-mess-javascript-namespacing/" visual="mikecavaliere.com/your-js-is-a-mess-javascript-namespacing/">Your JS is a Mess</url>
at <c>mikecavaliere.com/your-js-is-a-mess-javascript-namespacing/</c>.
</p>
</subsection>
JSXGraph is a “cross-browser JavaScript library for interactive geometry, function plotting, charting, and data visualization in the web browser.” Now a
8
jsxgraph.uni-bayreuth.de
<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 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.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 Archimedean Spiral is taken from the JSXGraph example wiki. The code could be written in 7 lines. Width is 80% and aspect ratio is 4:3.
9
jsxgraph.uni-bayreuth.de/wiki/index.php/Archimedean_spiral
10
jsxgraph.uni-bayreuth.de/wiki/index.php/Category:Examples
Here is a more elaborate example, from the JSXGraph Showcase, titled Infinity.
11
jsxgraph.uni-bayreuth.de/showcase/
12
jsxgraph.uni-bayreuth.de/showcase/infinity.html
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.
Here are the two new examples. They have been included in a , the left being Fermat’s Spiral and the right being a demonstration of B-splines.
sidebyside
layout element with equal widths (see Section 25) 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 JSXGraph example wiki13
jsxgraph.uni-bayreuth.de/wiki/index.php/Category:Examples
Instructions.
View Source for instructions
<instructions>
<p>
Drag the slider to change the curve.
</p>
</instructions>
Drag the slider to change the curve.
Instructions.
View Source for instructions
<instructions>
<p>
Any of the 8 red control points may be moved anywhere.
</p>
</instructions>
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.Generally, we load an interactive into an HTML at
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 Mess14
mikecavaliere.com/your-js-is-a-mess-javascript-namespacing/
mikecavaliere.com/your-js-is-a-mess-javascript-namespacing/
.Subsection 13.5 JessieCode
View Source for subsection
<subsection>
<title>JessieCode</title>
<idx>JessieCode</idx>
<p>
<url href="https://jsxgraph.uni-bayreuth.de/wp/docs_jessiecode/" visual="jsxgraph.uni-bayreuth.de/wp/docs_jessiecode/">JessieCode</url>
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 <tag>div</tag> element as you would for any other JSXGraph interactive plot and then provide the JessieCode script,
which focuses on the geometric elements.
</p>
<p>
Because JessieCode is provided by JSXGraph,
the interactive platform is <c>jsxgraph</c>.
The <tag>slate</tag>, however,
uses <attr>surface</attr> with value <c>jessiecode</c>.
The script can be embedded directly in your code.
As usual, you would need to remember to escape the special characters.
JessieCode uses <c><</c> and <c>></c> for inequalities as well as for declaring objects used to style geometric elements,
and <c>&&</c> is the boolean AND operator.
Alternatively, you can provide the file as a separate resource,
providing the URL with a <attr>source</attr> attribute.
Attributes defining the JSXBoard at the time it is created should be included as attributes of the <tag>slate</tag>,
including <attr>boundingbox</attr>,
<attr>axis</attr>, and <attr>grid</attr>.
</p>
<p>
For this first example,
the JessieCode was included directly in the XML source as the contents of the associated slate.
</p>
<figure xml:id="figure-quadratic-slope">
<caption>Finding the Tangent Line of a Quadratic Function</caption>
<interactive xml:id="interactive-quadratic-tangent" platform="jsxgraph" width="80%">
<slate xml:id="quadratic-tangent-plot" surface="jessiecode" axis="true" grid="false">
a = slider([-4.5,4], [-1.5,4], [-2,1,2])
<<
name:"a",
snapWidth:0.25,
point1: << frozen: true >>,
point2: << frozen: true >>
>>;
b = slider([-4.5,3.5], [-1.5,3.5], [-4,-1,4])
<<
name:"b",
snapWidth:0.5,
point1: << frozen: true >>,
point2: << frozen: true >>
>>;
c = slider([-4.5,3], [-1.5,3], [-4,0,4])
<<
name:"c",
snapWidth:0.5,
point1: << frozen: true >>,
point2: << frozen: true >>
>>;
fGraph = functiongraph(function(x) {
return a.Value()*x^2 + b.Value()*x + c.Value();
});
P = glider(1,0, fGraph);
Q = point(2,2)
<< name:"P" >>;
secant = line(P,Q)
<< color: (function() {
m = (Q.Y() - P.Y())/(Q.X() - P.X());
dydx = 2*a.Value()*P.X() + b.Value();
cVal = "red";
if (abs(m-dydx) < 0.001) {
cVal = "blue";
}
return cVal;
})
>>;
dydxValue = text(-4, 1.5, function() {
m = 2*a.Value()*P.X() + b.Value();
return ("dy/dx = " + trunc(m,3));
})
<< frozen: true >>;
mValue = text(-4, 1, function() {
m = (Q.Y() - P.Y())/(Q.X() - P.X());
return ("m = " + trunc(m,3));
})
<< frozen: true >>;
</slate>
<instructions>
<p>
Use the sliders to set the parameters of the quadratic <m>f(x)=ax^2+bx+c</m>.
Drag the point <m>A</m> on the graph and the point <m>P</m> to define a line.
Try to make the line tangent at the point at <m>A</m> and observe the resulting slope of the tangent line.
</p>
</instructions>
</interactive>
</figure>
<p>
For this second example,
the JessieCode was included through an associated script file,
loaded by the browser.
</p>
<figure xml:id="figure-nondifferentiable-oscillation">
<caption>Graph of a function that is continuous but not differentiable at <m>x=0</m> because the slope of the secant line has no limit.</caption>
<interactive xml:id="interactive-oscillating-secant" platform="jsxgraph" width="90%">
<slate xml:id="graph-cts-not-diff-function" surface="jessiecode" source="code/jsxgraph/cts-not-diff-oscillate.jc" axis="true" />
<instructions>
<p>
Drag the point <m>B</m> to move the point on the graph and change the secant line.
Notice that there is no well-defined limiting tangent line as <m>x \to 0</m>.
</p>
</instructions>
</interactive>
</figure>
</subsection>
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
15
jsxgraph.uni-bayreuth.de/wp/docs_jessiecode/
<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.
For this second example, the JessieCode was included through an associated script file, loaded by the browser.
Subsection 13.6 Sage Interacts
View Source for subsection
<subsection>
<title>Sage Interacts</title>
<idx><h>Sage</h><h>interacts</h></idx>
<p>
Sage, and the Sage Cell Server,
support interactive demonstrations,
called <term>interacts</term>.
<ul>
<li>
The interactive elements are nearly trivial to construct.
</li>
<li>
An interact is simply a single Python function
(acted on by a decorator).
</li>
<li>
You have the full mathematical power of Sage at your disposal,
so can do some very powerful computations with high precision
(or exactly).
</li>
<li>
The interface is not as polished as what you can achieve with Javascript libraries.
</li>
<li>
Graphics refresh with a round-trip to the server,
so are not nearly as fluid as with other tools.
</li>
</ul>
Note that each interact is insulated from the others,
unlike our other employment of the Sage Cell Server.
</p>
<p>
This example is by Marshall Hampton, taken from the
<url href="https://wiki.sagemath.org/interact/calculus" visual="wiki.sagemath.org/interact/calculus">Sage interact wiki</url>,
specifically
<url href="https://wiki.sagemath.org/interact/calculus#Numerical_integrals_with_the_midpoint_rule" visual="wiki.sagemath.org/interact/calculus#Numerical_integrals_with_the_midpoint_rule">Numerical integrals with the midpoint rule</url>.
</p>
<figure xml:id="figure-interactive-numerical-integral">
<caption>Numerical integrals using the midpoint rule</caption>
<interactive xml:id="interactive-numerical-integral" platform="sage" width="100%" aspect="4:5">
<slate surface="sage">
var('x')
@interact
def midpoint(n = slider(1,100,1,4), f = input_box(default = "x^2", type = str, width=40), start = input_box(default = "0", type = str, width=6), end = input_box(default = "1", type = str,width=6)):
a = N(start)
b = N(end)
func = sage_eval(f, locals={'x':x})
dx = (b-a)/n
midxs = [q*dx+dx/2 + a for q in range(n)]
midys = [func(x=x_val) for x_val in midxs]
rects = Graphics()
for q in range(n):
xm = midxs[q]
ym = midys[q]
rects = rects + line([[xm-dx/2,0],[xm-dx/2,ym],[xm+dx/2,ym],[xm+dx/2,0]], rgbcolor = (1,0,0)) + point((xm,ym), rgbcolor = (1,0,0))
min_y = min(0, find_local_minimum(func,a,b)[0])
max_y = max(0, find_local_maximum(func,a,b)[0])
pretty_print(html('<h3>Numerical integrals with the midpoint rule</h3>'))
pretty_print(html('$\\int_{a}^{b}{f(x) dx} {\\approx} \\sum_i{f(x_i) \\Delta x}$'))
print("\n\nSage numerical answer: " + str(integral_numerical(func,a,b,max_points = 200)[0]))
print("Midpoint estimated answer: " + str(RDF(dx*sum([midys[q] for q in range(n)]))))
show(plot(func,a,b) + rects, xmin = a, xmax = b, ymin = min_y, ymax = max_y,figsize=5)
</slate>
</interactive>
</figure>
</subsection>
Sage, and the Sage Cell Server, support interactive demonstrations, called interacts.
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, specifically Numerical integrals with the midpoint rule.
16
wiki.sagemath.org/interact/calculus
17
wiki.sagemath.org/interact/calculus#Numerical_integrals_with_the_midpoint_rule
Subsection 13.7 Geogebra
View Source for subsection
<subsection>
<title>Geogebra</title>
<p>
To embed a GeoGebra applet as-is from GeoGebra's Classroom Resources site
(by material ID),
see <xref ref="subsection-geogebra-server" text="type-global" />.
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
<q>Apps</q>
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.
</p>
<p>
Do one of the following:
<ol>
<li>
Identify a material ID from GeoGebra's Classroom Resources site.
You might even make the material yourself on that site.
</li>
<li>
Obtain a <c>.ggb</c> 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 <c>.ggb</c> file,
you can decode the string and save the result.
For example,
at <url href="https://www.opinionatedgeek.com/codecs/base64decoder" />.
</li>
<li>
Obtain a base64 encoded string for a GeoGebra applet.
You might first open a <c>.ggb</c> 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.
</li>
<li>
None of the above, with the intention to make an applet from scratch.
</li>
</ol>
</p>
<p>
Then mimic the examples that follow,
using GeoGebra API commands documented at
<url href="https://wiki.geogebra.org/en/Reference:GeoGebra_Apps_API">Geogebra API Manual</url>,
but do not include the <c>ggbApplet.</c> or <c>applet.</c> used in examples to prefix the functions<mdash />that part of the code will be provided automatically by <pretext />.
</p>
<p>
Jack Green created an applet on the Classroom Resources site with ID <c>D4s2v4ft</c>,
which you may view at <url href="https://www.geogebra.org/m/D4s2v4ft" visual="www.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 <m>y</m>-axis ticks be separated <m>5</m> apart instead of <m>10</m> apart.
We also decide we want a different aspect ratio and overall width.
One gotcha: the original applet is loaded and then <pretext /> uses <attr>width</attr> and <attr>aspect</attr> 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
<url href="https://wiki.geogebra.org/en/Reference:GeoGebra_Apps_API" visual="wiki.geogebra.org/en/Reference:GeoGebra_Apps_API">Geogebra API Manual</url>.
It is important to use one command per line.
</p>
<figure>
<caption>GeoGebra: modified material ID</caption>
<interactive xml:id="geogebra-train-distance" platform="geogebra" width="75%" aspect="2:1">
<slate xml:id="train-distance" surface="geogebra" material="D4s2v4ft" aspect="2:1">
setAxisSteps(1, 1, 5, 1);
setCoordSystem(-0.7, 8, -6, 56);
enableShiftDragZoom(false);
</slate>
</interactive>
</figure>
<p>
The same can be done with a <c>.ggb</c> 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.
</p>
<figure>
<caption>GeoGebra: <c>.ggb</c> file</caption>
<interactive xml:id="geogebra-astroid-original" platform="geogebra" width="100%" aspect="4:3">
<slate xml:id="astroid-original" surface="geogebra" source="code/rosoff/astroid.ggb" aspect="4:3" />
</interactive>
</figure>
<p>
Now we modify David's applet in a few ways.
</p>
<figure>
<caption>GeoGebra: modified from <c>.ggb</c> file</caption>
<interactive xml:id="geogebra-astroid" platform="geogebra" width="100%" aspect="4:3">
<slate xml:id="astroid" surface="geogebra" source="code/rosoff/astroid.ggb" aspect="4:3">
setCoordSystem(-6, 10, -6, 6);
setLabelVisible("b", false);
setLabelVisible("c", false);
setLabelVisible("d", false);
setAxisLabels(1,"x","y","z");
evalCommand("r = Slider(1,4,0.1)");
showResetIcon(true);
</slate>
</interactive>
</figure>
<figure>
<caption>GeoGebra: modified from <c>.ggb</c> file</caption>
<interactive xml:id="geogebra-cycloid" platform="geogebra" width="100%" aspect="2:1">
<slate xml:id="cycloid" surface="geogebra" source="code/rosoff/epi-hypocycloids-default.ggb" aspect="2:1">
setCoordSystem(-15,5,-5,5);
setAnimating("θ", true);
</slate>
</interactive>
</figure>
<p>
In 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.
</p>
<figure>
<caption>GeoGebra: a constructive
<q>proof</q>
that SAS congruence holds in Euclidean geometry (from Tevian Dray)</caption>
<interactive xml:id="geogebra-SAS" platform="geogebra" width="100%" aspect="1:1">
<slate xml:id="SAS" surface="geogebra" source="code/dray/SAS.ggb" aspect="1:1" />
<instructions>
<p>
Drag some of the points and some of the circles to change them,
and watch the remainder react.
</p>
</instructions>
</interactive>
</figure>
<p>
You could also use a base64-encoded string of the <c>.ggb</c> file.
You might come across such a string somewhere,
or you might generate one by opening a <c>.ggb</c> 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 <attr>base64</attr> attribute in place of the <attr>source</attr> 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.
</p>
<p>
The next example shows how you can communicate between a GeoGebra applet and a <tag>slate</tag> contained in the interactive.
The process is mediated by javascript code specified in the <attr>source</attr> attribute of the interactive.
Event listeners in the code update the HTML when the diagram changes or vice-versa.
MathJax is also notified when it needs to update math.
</p>
<p>
Note that this example has a <tag>slate</tag> whose <attr>surface</attr> is <c>pretext</c> <em>and</em>
a <tag>slate</tag> whose <attr>surface</attr> is <c>html</c>,
the latter requiring a namespace declaration.
The former produces HTML according to the <pretext /> templates,
which is fairly predictable,
but never guaranteed to always be identical over time.
A <pretext /> slate uses familiar syntax,
produces results styled consistently,
but might break in the future.
While an HTML slate is similar,
the results will not be styled,
but it does allow for a wider range of HTML elements (a <c>button</c> element here) and will not change over time.
</p>
<p>
The indefinite integral in the last row of the table is a gratuitious test that aurhors' macros from <tag>docinfo</tag> are available to MathJax.
Finally, a <pretext /> slate will only recognize <tag>p</tag>,
<tag>tabular</tag>,
<tag>sidebyside</tag>, and <tag>sbsgroup</tag> as children.
Make a feature request if you have a good case for more.
</p>
<figure xml:id="figure_Interactive-3d-direction-vector">
<caption>Geogebra/<pretext /> Communications</caption>
<interactive platform="geogebra" aspect="10:8" width="100%" xml:id="ggb_3d-direction-vector_interactive" source="code/haynes/3d-direction-vector.js">
<slate xml:id="ggb_3d-direction-vector_slate" aspect="10:5" surface="geogebra" source="code/haynes/3d-direction-vector.ggb">
evalCommand("B2 = 3");
evalCommand("C2 = -1");
evalCommand("D2 = 2");
evalCommand("B3 = -1");
evalCommand("C3 = 4");
evalCommand("D3 = 1");
setValue("showAB",true);
setValue("showBA",false);
evalCommand("ZoomIn(-Z,-Z,-Z/2,Z,Z,Z/2)");
evalCommand("SetViewDirection((1,1,1/2))");
enableRightClick(false);
</slate>
<sidebyside width="35%" margins="10%">
<slate surface="pretext" label="ggb_2__17_table1">
<tabular halign="right">
<col width="10%" halign="center" />
<col width="10%" halign="center" />
<col width="10%" halign="center" />
<col width="10%" halign="center" />
<col width="30%" halign="right" />
<row bottom="minor">
<cell> <m>\ </m> </cell>
<cell> <m>x </m> </cell>
<cell> <m>y</m> </cell>
<cell> <m>z </m> </cell>
<cell />
</row>
<row>
<cell> <m>\mathbf{A}</m> </cell>
<cell />
<cell />
<cell />
<cell />
</row>
<row>
<cell> <m>\mathbf{B}</m> </cell>
<cell />
<cell />
<cell />
<cell />
</row>
<row>
<cell><m>\indefiniteintegral{x^4}{x}</m></cell>
<cell />
<cell />
<cell />
<cell />
</row>
</tabular>
</slate>
<slate surface="html">
<p xmlns="http://www.w3.org/1999/xhtml">
<button id="a_to_b">Show A to B</button>
<button id="b_to_a">Show B to A</button>
</p>
</slate>
</sidebyside>
<sidebyside>
<p label="info" />
</sidebyside>
<instructions>
<p>
This interactive shows <m>\vec{r}_{AB}</m>,
the displacement vector from <m>\vec{A}</m> to <m>\vec{B}</m> and the corresponding unit displacement vector <m>\lambda_{AB}</m>.
</p>
<p>
You may change <m>\vec{A}</m> and <m>\vec{B}</m> by moving the red and blue dots.
Click the dot to switch between <m>x</m>-<m>y</m> mode and <m>z</m> mode.
Coordinates of <m>\vec{A}</m> and <m>\vec{B}</m> can also be entered into the table directly.
</p>
</instructions>
</interactive>
</figure>
<p>
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 <c>setFixed</c> 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.
Note that the GeoGebra scripting command <c>setAttribute</c> also changes the webpage's focus,
so it is better to set the perspective using an attribute of the slate.
</p>
<figure>
<caption>GeoGebra: from scratch</caption>
<interactive xml:id="geogebra-seed-head" platform="geogebra" width="50%" aspect="1:1">
<slate xml:id="seed-head" surface="geogebra" aspect="1:1" perspective="G">
setRounding("3s");
setCoordSystem(-1,1,-1,1);
setGridVisible(false);
setAxesVisible(false, false);
evalCommand("f(x)=If(x>0,sqrt(x),0)");
setVisible("f", false);
evalCommand("T=20");
evalCommand("t=Slider(0,T)");
setAnimating("t", true);
evalCommand("v=Vector((cos(t),sin(t)))");
evalCommand("r=Slider(0,1)");
evalCommand("r=(sqrt(5)-1)/2");
evalCommand("r=Slider(0,1,0.001)");
evalCommand("N=Min(100,floor(T/r))");
evalCommand("Seeds = Sequence(f(t - n r) / sqrt(T) (cos(n r 2 pi), sin(n r 2 pi)), n, 0, N)");
setFixed("v", false, false);
setFixed("Seeds", false, false);
</slate>
</interactive>
</figure>
</subsection>
To embed a GeoGebra applet as-is from GeoGebra’s Classroom Resources site (by material ID), see Subsection 14.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:
Then mimic the examples that follow, using GeoGebra API commands documented at Geogebra API Manual, but do not include the
18
wiki.geogebra.org/en/Reference:GeoGebra_Apps_API
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 . It is important to use one command per line.
D4s2v4ft
, which you may view at www.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 Geogebra API Manual19
wiki.geogebra.org/en/Reference:GeoGebra_Apps_API
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.Now we modify David’s applet in a few ways.
In 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.
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.The next example shows how you can communicate between a GeoGebra applet and a
<slate>
contained in the interactive. The process is mediated by javascript code specified in the @source
attribute of the interactive. Event listeners in the code update the HTML when the diagram changes or vice-versa. MathJax is also notified when it needs to update math.Note that this example has a
<slate>
whose @surface
is pretext
and a <slate>
whose @surface
is html
, the latter requiring a namespace declaration. The former produces HTML according to the PreTeXt templates, which is fairly predictable, but never guaranteed to always be identical over time. A PreTeXt slate uses familiar syntax, produces results styled consistently, but might break in the future. While an HTML slate is similar, the results will not be styled, but it does allow for a wider range of HTML elements (a button
element here) and will not change over time.The indefinite integral in the last row of the table is a gratuitious test that aurhors’ macros from
<docinfo>
are available to MathJax. Finally, a PreTeXt slate will only recognize <p>
, <tabular>
, <sidebyside>
, and <sbsgroup>
as children. Make a feature request if you have a good case for more.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. Note that the GeoGebra scripting command setAttribute
also changes the webpage’s focus, so it is better to set the perspective using an attribute of the slate.Subsection 13.8 CircuitJS
View Source for subsection
<subsection>
<title>CircuitJS</title>
<p>
<url href="https://www.falstad.com/circuit/" visual="www.falstad.com/circuit">CircuitJS</url>
is an electronic circuit simulator.
A circuit can be described by a language,
which PreTeXt will interpret and submit for rendering.
The next two examples are identical,
but provided in slightly different ways,
see the <pretext /> source for more.
Preview images for PDF will be added later.
</p>
<figure xml:id="figure-circuitjs-attribute">
<caption>CircuitJS Example (source via an encoded attribute)</caption>
<interactive xml:id="interactive-circuitjs-attribute" circuitjs="$ 1 0.000005 10.20027730826997 58 5 50 5e-11%0AR 464 32 464 -16 0 0 40 3.3 0 0 0.5%0Ag 464 224 464 240 0 0%0As 464 32 464 128 0 0 false%0As 464 128 464 224 0 1 false%0Ax 274 181 431 184 4 12 bottom\sswitch\s(to\sground)%0Ax 312 85 426 88 4 12 top\sswitch\s(to\sVdd)%0AO 464 128 544 128 1 0%0Ax 532 110 593 113 4 12 output\spin" width="90%" aspect="4:3" />
</figure>
<figure xml:id="figure-circuitjs">
<caption>CircuitJS Example (source authored directly)</caption>
<interactive xml:id="interactive-circuitjs" circuitjs="" width="90%">
<source>
$ 1 0.000005 10.20027730826997 58 5 50 5e-11
R 464 32 464 -16 0 0 40 3.3 0 0 0.5
g 464 224 464 240 0 0
s 464 32 464 128 0 0 false
s 464 128 464 224 0 1 false
x 274 181 431 184 4 12 bottom\sswitch\s(to\sground)
x 312 85 426 88 4 12 top\sswitch\s(to\sVdd)
O 464 128 544 128 1 0
x 532 110 593 113 4 12 output\spin
</source>
</interactive>
</figure>
</subsection>
CircuitJS is an electronic circuit simulator. A circuit can be described by a language, which PreTeXt will interpret and submit for rendering. The next two examples are identical, but provided in slightly different ways, see the PreTeXt source for more. Preview images for PDF will be added later.
20
www.falstad.com/circuit
Subsection 13.9 IFrames from Files
View Source for subsection
<subsection xml:id="interactive-iframes-local">
<title>IFrames from Files</title>
<p>
An <c>iframe</c> is an <init>HTML</init> element that allows embedding of a complete web page within another one.
Here we use this device to provide interactive 3D diagrams built with other tools.
</p>
<p>
We begin with a Jupyter notebook hosted on <url href="https://cocalc.com" visual="CoCalc.com" />.
News of success on other hosts for Jupyter notebook servers will allow us to expand this description.
We use a Sage kernel and create a 3D surface suggested by Juan Carlos Bustamante:
<cd>
<cline>var('x,y')</cline>
<cline>plot3d(x^2 - y^2, (x,-1,1), (y,-1,1), color="orange", mesh=true)</cline>
</cd>
News of other computational engines that produce similar graphics will also allow us to further expand this description.
Note that for the case of Sage 3D plots,
support for the <tag>sageplot</tag> element makes this even easier.
For example, see <xref ref="figure-sage-implicit-surface" />.
</p>
<p>
A button in the lower right allows for several options,
one is <c>Save as HTML</c>,
which will produce a complete self-contained web page we can recycle.
We save this file with our other externally-created images,
in a directory that we choose to name <c>iframe</c><mdash />you can use another name.
Then we make an <tag>interactive</tag> with an <attr>iframe</attr> attribute that has the filename,
starting from <c>iframe/</c> (in other words,
do not include the name of your managed directory of external images).
</p>
<figure xml:id="figure-sage-jupyter-iframe">
<caption>Sage+Jupyter <c>iframe</c></caption>
<interactive xml:id="interactive-sage-jupyter-iframe" iframe="iframe/sage-jupyter.html" width="95%" aspect="1:1" />
</figure>
<p>
Note that the downloaded file has links to specific versions of the <c>three.js</c> library,
which are beyond our control, and beyond your control.
So there is a future where these images may need updating.
You could put your source code into a (large) comment with your project's source for safe-keeping in the future.
See <xref ref="interactive-iframes-server" text="type-global" /> for the server version.
</p>
</subsection>
An
iframe
is an HTML element that allows embedding of a complete web page within another one. Here we use this device to provide interactive 3D diagrams built with other tools.We begin with a Jupyter notebook hosted on
CoCalc.com
. News of success on other hosts for Jupyter notebook servers will allow us to expand this description. We use a Sage kernel and create a 3D surface suggested by Juan Carlos Bustamante:var('x,y') plot3d(x^2 - y^2, (x,-1,1), (y,-1,1), color="orange", mesh=true)
News of other computational engines that produce similar graphics will also allow us to further expand this description. Note that for the case of Sage 3D plots, support for the
<sageplot>
element makes this even easier. For example, see 9.26.A button in the lower right allows for several options, one is
Save as HTML
, which will produce a complete self-contained web page we can recycle. We save this file with our other externally-created images, in a directory that we choose to name iframe
—you can use another name. Then we make an <interactive>
with an @iframe
attribute that has the filename, starting from iframe/
(in other words, do not include the name of your managed directory of external images).Note that the downloaded file has links to specific versions of the
three.js
library, which are beyond our control, and beyond your control. So there is a future where these images may need updating. You could put your source code into a (large) comment with your project’s source for safe-keeping in the future. See Subsection 14.4 for the server version.Subsection 13.10 threejs
View Source for subsection
<subsection xml:id="interactive-threejs">
<title>threejs</title>
<p>
Once upon a time there was an example here using the <c>threejs</c> 3D Javascript library.
It was
<url href="https://threejs.org/examples/#webgl_geometry_extrude_splines" visual="threejs.org/examples/#webgl_geometry_extrude_splines">one of the project's examples</url>,
licensed with an MIT License,
with minimal modifications.
</p>
<p>
But it would seem to have become a bit more complicated to embed and our example was not rendering.
As of 2022-08-08, we have removed it.
Of course, you can find it in the git repository,
perhaps searching on the date string just mentioned.
It woulld be interesting to see if our <tag>interactive</tag> framework could still support the changes.
</p>
<p>
The following two examples are meant to be instructive
(<em>only</em>).
The end result is accomplished in a much more straightforward way be the method in <xref ref="interactive-iframes-local" text="type-global" />.
We illustrate a way to get a <c>three.js</c> image out of an <init>HTML</init> page as a Javascript file and render it on a <pretext /> <tag>slate</tag>.
We follow the second method in a
<url href="https://golem.ph.utexas.edu/category/2017/12/sagemath_and_3d_models_in_webp.html" visual="golem.ph.utexas.edu/category/2017/12/sagemath_and_3d_models_in_webp.html">blog post from the <m>n</m>-Category Cafe</url>.
<ol>
<li>
Open a Jupyter Notebook that utilizes a Sage kernel.
This can be done easily at
<url href="https://cocalc.com" visual="cocalc.com">CoCalc</url>
(and for free initially).
</li>
<li>
Sketch a surface using Sage code.
We recycle the suggestion from Juan Carlos Bustamante in <xref ref="interactive-iframes-local" text="type-global" />:
<cd>
<cline>var('x,y')</cline>
<cline>plot3d(x^2 - y^2, (x,-1,1), (y,-1,1), color="orange", mesh=true)</cline>
</cd>
</li>
<li>
Look for a button
(in the lower-right)
which will provide a menu option <c>Save as HTML</c>.
Save the resulting <init>HTML</init> file,
and open a <em>copy</em> in a text editor.
</li>
<li>
<p>
You are now looking for two <init>HTML</init> <c>script</c> elements.
One will tell you just which version of <c>three.js</c> is being used,
vis a <c>@src</c> attribute.
For the second example below we located
<cd>
<cline>https://cdn.jsdelivr.net/gh/sagemath/threejs-sage@r122/build/three.min.js</cline>
</cd>
The <c>@r122</c> will likely be a version number,
which is a good thing for the longevity of your work.
This will get used in the <attr>source</attr> attribute of your <tag>interactive</tag>,
which will have <attr>platform</attr> set to <c>javascript</c>.
</p>
<p>
The second <c>script</c> element is likely huge and has many generic functions defined it.
There may be a huge variable full of data points computed by Sage.
Copy the <em>contents</em> of this <c>script</c> element into a new Javascript file
(so use a <c>.js</c> extension).
Do not edit in any way until you read further.
Once adjusted,
this file too gets specified in the <attr>source</attr> attribute of your <tag>interactive</tag>.
</p>
</li>
<li>
Your <tag>interactive</tag> needs a <tag>slate</tag> element for the graphic to draw on,
and you will need to give it a proper <attr>xml:id</attr> attribute,
plus teh <attr>surface</attr> will be set to <c>div</c>.
Then you need to edit the Javascript file to connect the graphic with the slate,
via IDs in your <pretext /> source and on teh <init>HTML</init> <c>div</c> created by the slate.
Look at the provided examples to see how.
Do not make any other edits to this file, even if tempted.
</li>
<li>
Study the two examples below,
and mimic how they were constructed.
</li>
</ol>
</p>
<p>
First, the example given in the blog post referenced above.
</p>
<figure xml:id="figure-threejs-catenoid-surface">
<caption><c>threejs</c> catenoid surface, from <m>n</m>-Category Cafe</caption>
<interactive xml:id="interactive-threejs-catenoid-surface" platform="javascript" width="75%" aspect="2:1" source="https://cdn.rawgit.com/mrdoob/three.js/r80/build/three.min.js https://cdn.rawgit.com/mrdoob/three.js/r80/examples/js/controls/OrbitControls.js code/threejs/catenoid.js">
<slate xml:id="threejs-catenoid-surface" surface="div" aspect="2:1" />
</interactive>
</figure>
<p>
Second, the example from JC Bustamante.
</p>
<figure xml:id="figure-threejs-saddle">
<caption><c>threejs</c> saddle by Sage</caption>
<interactive xml:id="interactive-threejs-saddle" platform="javascript" width="85%" aspect="1:1" source="https://cdn.jsdelivr.net/gh/sagemath/threejs-sage@r122/build/three.min.js code/threejs/saddle.js">
<slate xml:id="threejs-saddle" surface="div" aspect="1:1" />
</interactive>
</figure>
</subsection>
Once upon a time there was an example here using the , licensed with an MIT License, with minimal modifications.
threejs
3D Javascript library. It was one of the project’s examples21
threejs.org/examples/#webgl_geometry_extrude_splines
But it would seem to have become a bit more complicated to embed and our example was not rendering. As of 2022-08-08, we have removed it. Of course, you can find it in the git repository, perhaps searching on the date string just mentioned. It woulld be interesting to see if our
<interactive>
framework could still support the changes.The following two examples are meant to be instructive (only). The end result is accomplished in a much more straightforward way be the method in Subsection 13.9. We illustrate a way to get a .
three.js
image out of an HTML page as a Javascript file and render it on a PreTeXt <slate>
. We follow the second method in a blog post from the \(n\)-Category Cafe22
golem.ph.utexas.edu/category/2017/12/sagemath_and_3d_models_in_webp.html
- Open a Jupyter Notebook that utilizes a Sage kernel. This can be done easily at CoCalc(and for free initially).
23
cocalc.com
- Sketch a surface using Sage code. We recycle the suggestion from Juan Carlos Bustamante in Subsection 13.9:
var('x,y') plot3d(x^2 - y^2, (x,-1,1), (y,-1,1), color="orange", mesh=true)
- Look for a button (in the lower-right) which will provide a menu option
Save as HTML
. Save the resulting HTML file, and open a copy in a text editor. -
You are now looking for two HTML
script
elements. One will tell you just which version ofthree.js
is being used, vis a@src
attribute. For the second example below we locatedhttps://cdn.jsdelivr.net/gh/sagemath/threejs-sage@r122/build/three.min.js
The@r122
will likely be a version number, which is a good thing for the longevity of your work. This will get used in the@source
attribute of your<interactive>
, which will have@platform
set tojavascript
.The secondscript
element is likely huge and has many generic functions defined it. There may be a huge variable full of data points computed by Sage. Copy the contents of thisscript
element into a new Javascript file (so use a.js
extension). Do not edit in any way until you read further. Once adjusted, this file too gets specified in the@source
attribute of your<interactive>
. - Your
<interactive>
needs a<slate>
element for the graphic to draw on, and you will need to give it a proper@xml:id
attribute, plus teh@surface
will be set todiv
. Then you need to edit the Javascript file to connect the graphic with the slate, via IDs in your PreTeXt source and on teh HTMLdiv
created by the slate. Look at the provided examples to see how. Do not make any other edits to this file, even if tempted. - Study the two examples below, and mimic how they were constructed.
First, the example given in the blog post referenced above.
Second, the example from JC Bustamante.
Subsection 13.11 DoenetML
View Source for subsection
<subsection xml:id="interactive-doenetml">
<title>DoenetML</title>
<p>
<url href="https://doenet.org">DoenetML</url>
is a markup language inspired by <pretext /> for semantically describing interactive mathematics applets for the web.
Use <c>interactive[@platform="doenetml"]</c> with a <c>slate[@surface="doenetml"]</c> to include DoenetML content within your document.
</p>
<p>
Since DoenetML is similar to,
but not completely compatible with, XML, it cannot be authored directly within a PreTeXt document without painstakingly escaping every <c><</c> as <c>&lt;</c> and every <c>&</c> as <c>&amp;</c>.
However, a convenient workflow to avoid this is to author your DoenetML in a separate file like <c>example.doenetml</c>,
then include this file within your <pretext /> document using <c><xi:include parse="text" href="path/to/example.doenetml"/></c>.
</p>
<figure xml:id="figure-doenetml">
<caption>DoenetML example</caption>
<interactive label="interactive-doenetml-example" platform="doenetml" width="100%" aspect="3:2">
<slate surface="doenetml">
<p>
Adjust the vectors <m>\vec u</m>, <m>\vec v</m>, and <m>\vec w</m> in the
left graph to visualize the areas calculated by
<m>\det[\vec u\hspace{0.5em}\vec w]</m>, <m>\det[\vec v\hspace{0.5em}\vec w]</m>,
and
<m>\det[\vec u+\vec v\hspace{0.5em}\vec w]</m>.
</p>
<setup><line through="(0,0) $v" name="vLine"/><math simplify name="c">$cv.x/$v.x</math></setup>
<sideBySide>
<graph xmin="-4" ymin="-4" xmax="16" ymax="16">
<m draggable="false" anchor="(10,14)">
\det[\vec u\hspace{0.5em}\vec w],
\det[\vec v\hspace{0.5em}\vec w]
</m>
<point name="u" styleNumber="3">
(6,2)
<label><m>\vec u</m></label>
</point>
<point name="w" styleNumber="3">
(3,7)
<label><m>\vec w</m></label>
</point>
<point name="uPlusV" styleNumber="4">
(9,5)
<label><m>\vec v</m></label>
</point>
<polygon vertices="(0,0) $u $u+$w $w" filled draggable="false" styleNumber="3"/>
<polygon vertices="$u $uPlusV $uPlusV+$w $u+$w" filled draggable="false" styleNumber="4"/>
<lineSegment endpoints="(0,0) $uPlusV" styleNumber="6"/>
<lineSegment endpoints="$w $uPlusV+$w" styleNumber="6"/>
</graph>
<graph xmin="-4" ymin="-4" xmax="16" ymax="16">
<m draggable="false" anchor="(12,14)">
\det[\vec u+\vec v\hspace{0.5em}\vec w]
</m>
<polygon vertices="(0,0) $uPlusV $uPlusV+$w $w" filled draggable="false" styleNumber="2"/>
<point draggable="false" styleNumber="3">
$w
<label><m>\vec w</m></label>
</point>
<point draggable="false" styleNumber="4">
$uPlusV
<label><m>\vec u+\vec v</m></label>
</point>
<lineSegment endpoints="(0,0) $u" styleNumber="6"/>
<lineSegment endpoints="$u $uPlusV" styleNumber="6"/>
<lineSegment endpoints="$w $w+$u" styleNumber="6"/>
<lineSegment endpoints="$w+$u $w+$uPlusV" styleNumber="6"/>
</graph>
</sideBySide>
</slate>
</interactive>
</figure>
</subsection>
DoenetML is a markup language inspired by PreTeXt for semantically describing interactive mathematics applets for the web. Use
24
doenet.org
interactive[@platform="doenetml"]
with a slate[@surface="doenetml"]
to include DoenetML content within your document.Since DoenetML is similar to, but not completely compatible with, XML, it cannot be authored directly within a PreTeXt document without painstakingly escaping every
<
as <
and every &
as &
. However, a convenient workflow to avoid this is to author your DoenetML in a separate file like example.doenetml
, then include this file within your PreTeXt document using <xi:include parse="text" href="path/to/example.doenetml"/>
.