SVG Function Plotter
NOTE: This page contains MathML elements, which is not well supported by Chrome and Edge on Android devices, but Firefox does quite a good job and renders the equations nicely.
The SVG function plotter shall support one, two and three-dimensional functions, multiple coordinate system axes, and multiple graphs in the same SVG image.
Some examples (TODO):
About Coordinate Systems
The space of an SVG image is inherently two-dimesional. It is defined by the SVG element's viewBox attribute:
<svg viewBox = "-100, -100, 300, 300" ...
These values define the coordinates of the upper left corner xMin and yMin, width and height of the diagram. These values inherently define the location of the origin (0,0) in the image as well as xMax and yMax:
Note that the viewbox origin is always at viewbox coordinates (0,0):
Now let's make things complicated. The figure above suggest that the viewbox axes represent the axes x and y of a function graph. But in fact, they don't. One indicator is that the y axis goes from top to bottom, which is unusual, kind of. Secondly, the viewbox axes are invisible. In the diagrams presented here, I added some SVG code to make them visible. The tickmarks and their lables should give some guidance and orientation in the viewbox space.
Let's create an angled axis named "z":
Note that the axis can actually be oriented in any direction, and might not even go through the viewbox origin. In the following section, we will go into ways to define an axis and develop the related math equations.
Axis Definition in ViewBox Space
The web page author should have two methods define a diagram axis:
- An angle and an optional reference point, which defaults to the viewbox origin (0,0)
- Two reference points, the second is optional and defaults to (0,0)
The software should be able to caluclate the intersection points between axis line and viewbox border, as well as axis length in viewbox units and other transformation factors.
Method 1: Angle and Reference Point
The page author supplies an angle and an optional reference point. To keep things simple, we assume the default reference point, the viewbox coordinate system origin O at (0,0)).
The angle is measured counter-clockwise between the viewbox x axis and the graph axis. To draw the axis line, we need to find the coordinates of intersection points (P1, P2) between line and viewbox borders:
They are determined by the angle α and the length of the viewbox axes legs, xMin, xMax, yMin and yMax. We will have to treat each coordinate system quadrant and each axis line leg ( and ) separately.
Let's begin with the first quadrant in the upper right corner.
The figure above indicates that we have two different situations:
- The line intersects with the right viewbox border at P1
- The line intersects with the upper viewbox border at P2
The angle α and the viewbox properties xMax, xMin determine which of these alternatives applies.
We will use the trigonometric tangens relation for our calculations:
A visual help:
So tangens α essentially is the slope of the line .
Finding the X Coordinate
If we want to get the x coordinate of the intersection point, we set y in equation (1) to −yMin and solve for x:
The negative of yMin must be used in order to obtain a positive x value.
The two situations ( and ) are illustrated more detailed in the figure below:
If the line intersects with the right viewbox border, we get the point P1A with the x-coordinate x1 — which is outside of the viewbox. So we must limit the x-value to find P1:
In case 2, the line intersects with the upper viewbox border at P2. In this case, the solution is
x2 is less than xMax, so we can accept that.
Finding the Y Coordinate
Now lets find the y coordinate for a line in quadrant 1. Again, we have two situations:
- The line intersects with the right viewbox border at P1
- The line intersects with the upper viewbox border at P2
In detail:
We set x = −xMax in equation (1) and solve for y. We need a negative xMax to obtain a negative y-coordinate in this quadrant.
If the line crosses the right viewbox border at P1, we obtain y1, which is greater than yMin, so we can accept the result:
In the second case, the line intersects with the upper viewbox border, we get P2A with the coordinate y2 — which is outside of the viewbox area. So the result must be limited:
The Second Quadrant
The figure below shows the situation in the second quadrant. Here, both x and y coordinates are negative:
To keep things familiar, we will work with the complimentary angle β:
If the line intersects the left viewbox border, we get the x-coordinates xMin and y1:
If the line crosses the upper border of the viewbox, we get the following coordinates:
The Third Quadrant
This is the situation in the third quadrant:
Again, we work with the complimentary angle β:
If the line intersects the left viewbox border, we get the x-coordinates xMin and y1:
If the line crosses the upper border of the viewbox, we get the following coordinates:
Similar to quarant 1, we have to use negative values to obtain the correctly signed results.
The Fourth Quadrant
This is the situation in the third quadrant:
In this quadrant, all coordinate values are positive.
Again, we work with the complimentary angle β:
If the line intersects the left viewbox border, we get the x-coordinates xMin and y1:
If the line crosses the upper border of the viewbox, we get the following coordinates:
Equation Summary
After drowning in the details, it's good to regain an overview. Below are the eight equations used to calculate the coordinates:
The first quadrant:
The second quadrant:
The third quadrant:
The fourth quadrant:
A closer look at these equations reveals that the combinations are all slightly different for each quadrant. So, we cannot combine them.
Note that an axis lines has two legs at opposite quadrants, and each leg has to be calculated separately!
Angle and Reference Point
The following figure illustrates an axis line with the specified angle α through the reference point R:
If we assume the reference as new origin (0, 0), we get a transformed coordinate system:
The range values for the transformed coordinate system are obtained from these equations:
With these new values used in equations (2) to (12), we can calculate the axis end point coordinates as before.
Coordinate Calculation Test
Method 2: Two Reference Points
TO DO
Axis Length
The angled axis is obviously longer than the viewbox x and y axes:
Pythagoras, a well-respected ancient Greek, says:
The JavaScript Math object has a method for this purpose: hypot() computes the root of the sum of squares of arguments.
Axis Projection Parameters
Scaling factors for the projection of a point z onto the viewbox plane:
Axis
An SVG plotter axis represents a section of a dimension of the real-world space of a function to be plotted. It governs two transformations:
- from a dimension of the function "real-world" function space to the one-dimensional axis space
- from the axis space to the two-dimensional SVG viewbox space
The visual representation of an axis is a line with an arrow-head and label and a series of tickmarks with labels, representing real-world coordinates. The SVG viewbox space is shared between all axes.
Before diving into the properties, let's visually inspect the transformation from a real-world space to the SVG viewbox space of an axis.
Coordinate System Transformations
The SVG image projects a real-world data range (rwMin to rwMax) on the SVG viewbox range (vbMin to vbMax).
This is a simple projection without offset between origins, due to the fact that the ratio is equal to .
A more general projection is shown below, with real-world space above the axis line, and the SVG viewbox space below:
The real-world origin (0) is not projected on the viewbox origin (0) but at some offset (40). This shift is a consequence of the projection of the real-world data range on the viewbox data range.
The formula for the transformation from real-word to viewbox coordinates uses a scaling factor (SF) and an offset (vbOff):
Similarly, the transformation from SVG viewbox coordinates to real-world coordinates is done by
The second tranformation project the 1D axis space on the 2D viewbox space.
The orientation of an axis can be arbitrary and is defined by the angle (α), measured counterclockwise, value range is from 0 to 360 degrees. Zero degree corresponds to a horizontal axis, pointing to the right.
The black axes represent the viewbox axes of the SVG image. A circle at their intersection indicates the viewbox coordinate system origin (0,0). Note that the orientation of the y axis is down, not up as you might expect.
The green arrow, the z axis, represents a section of a function space dimension, with its origin (0) somewhat offset from the viewbox origin. Start and end points of this axis are projected on the viewbox axes, their viewbox coordinates are defined by the length of the axis (len) and the axis orientation angle (α).
Normally, the axis should extend to the image border, but for clarity, the z axis has been shortened a little bit.
SVG ViewBox Calculations
The viewbox coordinate system defines some fundamental values for the entire SVG image:
- vbXMin
- X axis minimum (left) value. Defined in the SVG element's viewBox x attribute.
- vbYLen
- X axis length. Defined in the SVG element's viewBox w attribute.
- vbXMax
- Length of the x axis. Computed.
- vbYMin
- Y axis minimum (top) value. Defined in the SVG element's viewBox y attribute.
- vbYLen
- Y axis length. Defined in the SVG element's viewBox h attribute.
- vbYMax
- Length of the y axis. Computed.
The viewbox coordinate system origin is always at (0,0).
Axis Properties Calculations
An axis line intersects the viewbox borders at two points. We need to find their coordinates in order to calculate their properties. Depending on which of the four viewbox sides an intersection point is located, one of four different formula sets has to be applied to find its coordinates.
But we are not yet there. Currently, we only know the axis orientation angle α1, supplied by the caller, and the viewbox properties, xMin, xMax, yMin and yMax:
To use the axis angle as selection criterium, we divide the viewbox into four areas, defined by the corners and the viewbox origin:
Then we can calculate the four angles φ1 to φ4:
Now we have the criteria to locate the intersection points in one of the four areas and calculate their coordinates:
NOTE that α2 can be calculated as α1 + 180 deg.
With the axis line coodinates at hand, we can calculate the axis length in viewbox units:
An axis has the following properties to support tranformations:
- axAngle α
- Axis orientation angle relative to the viewbox x axis, measured counter-clockwise. Range: 0 … 360 degree
- Input, discarded after computations.
- axMin
- Minimum axis coordinate value. Computed.
- If axAngle between 90 and 180 degree then
- Len
- Axis length, computed.
- SFX
- Scaling factor for the projection of axis values on the viewbox x axis. vbFTX = cos α
- SFY
- Scaling factor for the projection of axis values on the viewbox y axis. vbFTY = sin α
- vbMin
- viewbox range minimum (left) value
- Input
- vbLen
- viewbox range length, vbMax - vbLen
- Input
- vbMax
- viewbox range maxium (right) value
- Computed
- vbOff
- viewbox value for real-word zero
- Computed
- rwMin
- real-word range minimum (left) value
- Input or computed
- rwMax
- real-word range maximum (right) value
- Input or computed
- rwOff
- real-world offset value for viewbox zero.
- Input or computed
- SF
- Scaling factor, used to scale real-world coordinates to viewbox coordinates
- Computed
Depending on the two variables supplied by the user, one of the following calculation methods is used:
- rwMax and Offsrw given,
SF and Offsvb are calculated, rwMin is defined implicitly - rwMin and Offsrwgiven,
SF and Offsvb are calculated, rwMax is defined implicitly - rwMin and rwMaxgiven,
SF, Offsrw and Offsvb are calculated. Offsrw will most probably not be a non-integer number.
Method 1 has the disadvantage that the viewbox origin might not map to a "clean" rwOffset, which is required if tickmarks should have "regular" values like 0.1, 0.2, 0.3 etc. Methods 2 and 3 avoid that, because the rwOffset can be chosen freely.
The scaling factor can be computed in three ways, which are equivalent:
Depending on what's available, a suitable variant can be chosen.
Computation Examples
We will use the following projection for the calculation examples:
The following table outlines example 1 with input option 1:
Input | |
---|---|
vbMin | −100 |
vbLen | 300 |
rwMin | −0.7 |
rwMax | 0.8 |
Calculations | |
vbMax | = vbLen + vbMin = 300 − 100 = 200 |
rwLen | = rwMax − rwMin = 0.8 + 0.7 = 1.5 |
SF | = vbLen / rwLen = 300 / 1.5 = 200 |
rwOff | = rwMin − vbMin / SF = −0.7 + 100 / 200 = −0.7 + 0.5 = −0.2 |
vbOff | = −rwOff ⋅ SF = −0.2 ⋅ 200 = 40 |
The following table outlines example 1 with input option 2:
Input | |
---|---|
vbMin | −100 |
vbLen | 300 |
rwOff | −0.2 |
rwMax | 0.8 |
Computations | |
vbMax | = vbLen + vbMin = 300 − 100 = 200 |
SF | = vbMax / (rwMax − rwOff) = 200 / (0.8 + 0.2) = 200 |
rwMin | = vbMin / SF + rwOff = −100 / 200 − 0.2 = −0.5 − 0.2 = −0.7 |
rwLen | = rwMax − rwMin = 0.8 + 0.7 = 1.5 |
vbOff | = −rwOff ⋅ SF = 0.2 ⋅ 200 = 40 |
The following table outlines example 1 with input option 3:
Input | |
---|---|
vbMin | −100 |
vbLen | 300 |
rwOff | −0.2 |
rwMin | −0.7 |
Computations | |
vbMax | = vbLen + vbMin = 300 − 100 = 200 |
SF | = vbMin / (rwMin − rwOff) = −100 / (−0.7 + 0.2) = −100 / −0.5 = 200 |
rwMax | = vbMax / SF + rwOff = 200 / 200 − 0.2 = 1 − 0.2 = 0.8 |
rwLen | = rwMax − rwMin = 0.8 + 0.7 = 1.5 |
vbOff | = −rwOff ⋅ SF = 0.2 ⋅ 200 = 40 |
Tickmarks
Tickmarks on the axes should visualize the data range. They should be space equidistantly. To avoid rounding/dithering effect, the tickmark distance should be an integer value.
The tickmark distance is usually defined in value units. To continume the example, let's consider a tickmark distance of 0.1. We need to translate this value to viewbox coordinate:
So, we have a tickmark every 50 viewbox units, but the first and last tickmarks should not interfere with the axis ends.