# The joy of plotting functions with vanilla JavaScript

June 9, 2021

I wanted to plot a few mathemathical functions for a personal app I'm building and I thought it would be fun to build a tiny plotting library for mathematical functions whithout dependencies. Here's a summary of what I did.

It's worth emphasising that the only purpose of the library is to do simple plots, perhaps the topic of a different blog post is about the complexities and the challenges of defining an API for a general purpose plotting library (such as D3 or ggplot2), and I'd encourage anyone interested on the topic to take a look at The Grammar of Graphics

### Scales

If visualization is constructing “visual representations of abstract data to amplify cognition”, then perhaps the most important concept in D3 is the scale, which maps a dimension of abstract data to a visual variable.

The first thing you want to do is to define how every data point is going to be matched to a position on the screen.

To do this, you need to define the range of values that can be represented on the screen

In D3 you would normally use `d3.scaleLinear()`, and in Vega

### Drawing the curve

The strategy is to compute a bunch of values of the function, and use those points to draw the curve.

To draw the curve, we're going to use a `<path>` element, paths are ideal for this use case because they allow you to provide a series of commands to draw a line on the screen.

`<path>` accepts a `d` attribute, a string containing a series of commands that define the path to be drawn. For the purposes of this experiment, we're only interested in two commands:

• `M x y`, the move to command, moves the current point to the coordinate `x, y`.
• `L x y`, the line to command, moves the current point to the coordinate `x, y` and draws a line from the previous position to the current position.

If we have enough points, we can build a `d` attribute with an `L` command for each point.

``let command = "M";let d = "";for (const p = xdomain; p <= xdomain; p += 0.1) {  d += `\${command} \${x(p)} \${y(f(p))} `;  command = "L";}const curve = createSVG("path", { d, fill: "none", stroke: "orange" });``

### Resources

1. Wilkinson, Leland, and Graham Wills. The Grammar of Graphics. 2nd ed. Statistics and Computing. New York: Springer, 2005.
2. Mike Mobstock's funplot