A WebComponent canvas for plotting mathematical functions. Spiritual successor of adm-math.
This component defines the <math-plot>
element, which will plot a cartesian plane, and related subelements, which allow you to plot curves and otherwise mark up the plane.
The component is contained in three JavaScript files, math-plot.js
, mathml.js
and rational.js
. Simply download them into your project folder, ensuring that they are all in the same directory.
Before doing any development work, NPM dependencies need to be installed. Run:
$ npm install
The math-plot library uses the polylabel library to sensibly position some labels on its plots. As this is a NodeJS, not a frontend, library, it needs to be compiled using browserify. This step isn't needed for end-users, but will be needed if any changes need to be made to the NodeJS dependencies.
Any changes to node dependencies should be made in node-main.js
. Once the changes are made, run the command:
$ browserify node-main.js -o dependencies.js
The file dependencies.js
is automatically imported by math-plot.js
, so nothing more need be done.
Do not edit dependencies.js
, make changes in node-main.js
.
Testing is handled by Jest testing framework. To execute the tests, run npm run test
.
First, install the NPM dependencies (the only dependency is a polyfill to allow WebComponent support in old browsers and Edge). In the project directory, run:
$ npm install --production
In the HTML file, include the polyfill and the module:
<script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script>
<script type="module" src="math-plot.js"></script>
Then place the element as you would any other:
<math-plot></math-plot>
That will work, but doesn't give you much context. Here's a more realistic example: a sin
graph, plotted as you might in an actual application:
<math-plot range-x="(-2pi, 2pi)" range-y="(-1, 1)" pi-units>
<math-plot-function rule="<apply><sin/><ci>x</ci></apply>"></math-plot-function>
</math-plot>
Refer to examples/basic.html
to see a more examples of graphs.
The <math-plot>
element will create a canvas, and draw a cartesian plane on it. It implements the following attributes:
Attribute | Value | Default | Description |
---|---|---|---|
width | Integer | 300 | The width of the plot element. |
height | Integer | 300 | The height of the plot element. |
show-grid | No value | - | Show dotted lines across the graph at each unit marker. |
hide-x-axis | No value | - | Don't render the x axis. |
hide-y-axis | No value | - | Don't render the y axis. |
hide-origin | No value | - | Don't render the 0 marking the origin. |
pi-units | No value | - | Mark the x axis in multiples of π, e.g. for plotting circular functions. |
step-x | Rational* or MathML* | Calculated | The distance between unit markers on the x axis. |
step-y | Rational* or MathML* | Calculated | The distance between unit markers on the y axis. |
hide-x-units | No value | - | Don't show unit markers on the x axis. |
hide-y-units | No value | - | Don't show unit markers on the y axis. |
range-x | Rational pair* or MathML <list> * |
(-10, 10) | The x values between which the plane will be plotted. |
range-y | Rational pair* or MathML <list> * |
(-10, 10) | The y values between which the plane will be plotted. |
gutter-left | Integer | 20 | The space, in pixels, outside the range on the left which will also be plotted. |
gutter-right | Integer | 20 | The space, in pixels, outside the range on the right which will also be plotted. |
gutter-top | Integer | 20 | The space, in pixels, outside the range on the top which will also be plotted. |
gutter-bottom | Integer | 20 | The space, in pixels, outside the range on the bottom which will also be plotted. |
A Rational is an internal class, representing a rational number, optionally multiplied by π or e, e.g. "pi/2", "2e".
A Rational pair is a comma-separated pair of numbers, surrounded by brackets, e.g. "(-2pi, 2pi)".
Ideally, it should allow you to intuitively type a number, but here are some examples of acceptable Rationals:
Input | Number |
---|---|
"1" | 1 |
"pi" | π |
"-2pi" | -2π |
"1/2" | 0.5 |
"pi/2" | 0.5*pi |
Note: The main limitation is that floats are not accepted. You must input a fraction instead.
Many numbers in math-plot
can be provided using MathML. Although support for elements is not vast, it should include most commonly-used elements.
In particular, the range attributes can be provided as a MathML <list>
element. The notation for (0, 2pi)
, for instance, would be:
<list>
<cn>0</cn>
<apply><times/><cn>2</cn><pi/></apply>
</list>
The purpose of the gutters is to allow you to, for example, plot a sin
curve with range-x="(0, 2pi)"
without having the graph end abruptly beyond that range.
Should be included as a direct child of <math-plot>
. The <math-plot-function>
element will accept an argument rule
, a description of a function in content MathML, and plot that function.
Attribute | Value | Default | Description |
---|---|---|---|
rule | MathML* | Required | The function to be plotted. |
domain | Rational pair* or MathML <list> * |
None | The domain in which the function will be plotted. If undefined, the function will be plotted over its natural domain. |
color | CSS color descriptor | #000000 | The color of the plotted function. |
dashed | No value | - | If included, the curve will be dashed rather than solid. |
The following MathML elements are accepted:
Element | Notes |
---|---|
<cn> |
Only accepts numbers parseable by parseFloat() . |
<ci> |
Only accepts the value 'x'. |
<pi> |
The constant π |
<exponentiale> |
The constant e |
<degree> |
|
<logbase> |
|
<apply> |
See below |
The following <apply>
functions are implemented:
Function | Notes |
---|---|
<plus> |
|
<minus> |
|
<times> |
|
<divide> |
|
<power> |
|
<root> |
<degree> element is required, must be first argument. |
<sin> |
|
<cos> |
|
<tan> |
|
<arcsin> |
|
<arccos> |
|
<arctan> |
|
<abs> |
|
<log> |
<logbase> element is optional, but if included must be first argument. If not included, defaults to 10. |
<ln> |
Should be included as a direct child of <math-plot>
. The <math-plot-line>
element will accept two arguments point-a
and point-b
, and will plot the line running through both.
Attribute | Value | Default | Description |
---|---|---|---|
point-a | Rational pair* or MathML <list> * |
Required | A point that the line will run through. |
point-b | Rational pair* or MathML <list> * |
Required | A point that the line will run through. |
color | CSS color descriptor | #000000 | The color of the line. |
dashed | No value | - | If included, the curve will be dashed rather than solid. |
Should be included as a direct child of <math-plot>
. The <math-plot-line-sgment>
element will accept two arguments point-a
and point-b
, and will plot a line segment between the two.
Attribute | Value | Default | Description |
---|---|---|---|
point-a | Rational pair* or MathML <list> * |
Required | One end of the line segment. |
point-b | Rational pair* or MathML <list> * |
Required | One end of the line segment. |
label | String | None | A text label for the line segment. Will be written beside or above the line segment. |
color | CSS color descriptor | #000000 | The color of the line segment. |
dashed | No value | - | If included, the curve will be dashed rather than solid. |
Note: The logic for positioning the label is not sophisticated. If unsatisfactory, use the <math-plot-text>
element instead.
Should be included as a direct child of <math-plot>
. The <math-plot-asymtote>
element will one or both arguments x-intercept
or y-intercept
. With one, it will plot a vertical or horizontal asymptote running through that intercept. With both, it will plot a slanted asymptote running through both.
A <math-plot-asymptote>
element cannot take the dashed
attribute as an asymptote is by default dashed.
Attribute | Value | Default | Description |
---|---|---|---|
x-intercept | Rational* or MathML* | None | The x intercept of the asymptote. |
y-intercept | Rational* or MathML* | None | The y intercept of the asymptote. |
color | CSS color descriptor | #000000 | The color of the asymptote. |
Should be included as a direct child of <math-plot>
. The <math-plot-point>
element will mark a point at the position position
, optionally labelled with label
.
Attribute | Value | Default | Description |
---|---|---|---|
position | Rational pair* or MathML <list> * |
Required | The position of the point to be marked. |
label | String | None | A text label for the point. |
label-coordinates | No value | - | Label the point with the coordinates of the point in the form (a, b) . |
label-position | /^(top|bottom) (left|right)$/ | - | The position of the label with respect to the point. |
radius | Integer | 3 | The radius of the point in pixels. This default value can be changed using the POINTRADIUS global. |
color | CSS color descriptor | #000000 | The color of the point. |
The logic for positioning the label is not sophisticated, it's mostly placed to the bottom right unless it's near the edge of the plot. Its position can be controlled using the label-position
attribute, but for more precise control use the <math-plot-text>
element instead.
Only one of label
and label-coordinates
may be used on a single point. If both are present, label
will be shown.
Should be included as a direct child of <math-plot>
. The <math-plot-text>
element will render the text in the attribute text
on the plot.
Attribute | Value | Default | Description |
---|---|---|---|
text | String | Required | The string or character to be rendered. |
top* | Rational* or MathML* | None | The vertical position of the text, in coordinate units. |
bottom* | Rational* or MathML* | None | The vertical position of the text, in coordinate units. |
left* | Rational* or MathML* | None | The horizontal position of the text, in coordinate units. |
right* | Rational* or MathML* | None | The horizontal position of the text, in coordinate units. |
color | CSS color descriptor | #000000 | The color of the text. |
Only one of top
and bottom
will be used. If both are present, top
will be used. Similarly, for left
and right
, left
will be preferenced.
The position attributes should be given in terms of coordinates on the graph. A text element at top="1" left="1"
will be rendered with its top-left corner at the point (1, 1)
on the graph.
Should be included as a direct child of <math-plot>
. The <math-plot-floodfill>
element will floodfill a region described below.
Attribute | Value | Default | Description |
---|---|---|---|
rule-top | MathML* | None | The top of the region to be filled. |
rule-bottom | MathML* | None | The bottom of the region to be filled. |
domain | Rational pair* or MathML <list> * |
None | The domain in which the region will be filled. |
label | String | None | The text with which to label the the filled region. |
fill-color | CSS color descriptor | #d4d4d4 | The color of the filled region. |
color | CSS color descriptor | #000000 | The color of the label text. |
If both the rule-top
and rule-bottom
attributes are defined, the space between them will be filled regardless of which is on top across the entire domain
, even if they cross within the domain. You could, for example, plot the space between sin(x)
and the x
axis using:
<math-plot-floodfill
rule-top="<apply><sin/><ci>x</ci></apply>"
rule-bottom="<cn>0</cn>">
</math-plot-floodfill>
If only rule-top
is defined, the space between it and the bottom of the plot will be filled. If only rule-bottom
is defined, the space between it and the top of the plot will be filled.
If domain
is undefined, the region will be filled over the domain of the plot. This may result in unexpected behaviour if either rule-top
or rule-bottom
is not defined over the entire plot.