3D SVG Graph

Evan Boldt's picture


An SVG is a type of graphic that is defined by shapes and math instead of discrete pixels. So, it is scales nicely, but can't make photo-realistic images. An (currently) SVG is two dimensional. That does not mean, though, that we cannot represent 3D information in this 2D space. After all, it is shown in 2D anyway. To accomplish this, we will build our own 3D rotation matrices, and a 3D to 2D projection matrix. The 3D points can be multiplied by both of these matrices to make it appear 3D, albeit somewhat flat due to the orthographic projection.

Interactive Graph Demo

This SVG grapher was made so that a user easily visualize and control the end manipulator of a robotic arm in 3D through a web browser. It may be viewed on this page on the NIU College of Engineering and Engeering Technology website, but the arm is usually left off for safety.

Hold left click and drag to move point.
Hold middle click and drag to rotate.


Although the implementation starts to get somewhat complicated, the usage is actually somewhat straightforward. Get the attached javascript file, and make an html file that contains this:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="3dgraph.js"></script>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="320" width="352" id="3d-graph" style="height: 320px; width:342px; margin: 0 auto; padding: 5px;" >
    <!-- neg axis -->
    <line x1="100" y1="250" x2="400" y2="250" id="neg-axis-x" style="stroke:rgba(250,200,200,0.5);stroke-width:2"/>
    <line x1="100" y1="250" x2="100" y2="0"   id="neg-axis-y" style="stroke:rgba(200,250,200,0.5);stroke-width:2"/>
    <line x1="100" y1="250" x2="0" y2="400"   id="neg-axis-z" style="stroke:rgba(200,200,250,0.5);stroke-width:2"/>
    <!-- axis -->
    <line x1="100" y1="250" x2="400" y2="250" id="axis-x" style="stroke:rgb(200,0,0);stroke-width:2"/>
    <line x1="100" y1="250" x2="100" y2="0"   id="axis-y" style="stroke:rgb(0,200,0);stroke-width:2"/>
    <line x1="100" y1="250" x2="0" y2="400"   id="axis-z" style="stroke:rgb(0,0,200);stroke-width:2"/>


The coordinates of the point above are stored in the variables tx, ty, and tz. If you just wish to read it, just read the variables. If you modify them, you have to update the display with mainDot.changePoint()

A point is simply a vector. A dot is the point plus the graphical representation. A line is two points and a graphical connection between them.

How it Works

This implementation uses the jQuery library, which is much less useful than usual since jQuery can only create HTML DOM objects and not SVG DOM objects as required in this usage. It is still useful for it's event bindings and some search features.

There is a point class with an x, y, and z. Points are used to in the graphical classes Dot and Line, where line has two points for a start and an end. Points are multiplied by rotation and projection matrices to turn their 3 dimensions into 2 dimensions. The rotation matrix angles are modified by mouse movement during a click event. When the rotation matrix is changed, the points must be multiplied with the new matrix and the result must be updated on the SVG.

In this specific usage, there were 7 points used for the axes. A zero point and points at the maximum and minimum (positive and negative) for each direction. There is a dot at the point you want to visualize in the 3D space, as well as 3 guide lines to help with perspective. The guide lines are entirely necessary. It would also be possible to plot a curved line by using many Line classes or even making your own class that uses the SVG path tag to generate a smooth curve. Another possible feature might be to put a Dot class at a point on the lone closest to the mouse and showing the x,y, and z coordinates.