# Graphing Calculator, Part 2

Tue 09 July 2013

Filed under code

Welcome! This is part 2 of my documentation of writing a simple graphing calculator/function plotter using d3.js (see part 1 if you missed it). Today I will replace the line segments I used for plotting with the more involved (and actually easier to use, as you will see) SVG path element. Let's get started!

## Paths To Success

The SVG path element is different from the other elements like circle and line we've seen so far. Instead of adding a discrete circle or line to the graph for each datapoint, you add a single element which comprises all the datapoints, and whose components are described in a graphical language similar to Logo. For example:

```<svg width="100" height="100">
<path d=" M 25 25
L 25 75
L 75 75
L 75 25
L 25 25"
stroke="red" fill="none" />
</svg>
```

produces:

Don't worry about what M and L mean for now - these SVG path mini-language commands are abstracted away by d3. [1] Remember what I said above about not having to enter a distinct element for each datapoint in your set? For a path, d3 asks for a line() function which provides each of the points, plus an interpolation style which tells d3 how to draw lines between the explicitly plotted points.

We will change our previous code:

```svg.selectAll('#line_not_in_axis_tick')
.data(plotdata.slice(0, plotdata.length :html_entity:`mdash` 1))
.enter()
.append('svg:line')
.attr("x1", function(d, i) { return xScale(d[0]); })
.attr("y1", function(d, i) { return yScale(d[1]); })
.attr("x2", function(d, i) { return xScale(plotdata[i+1][0]); })
.attr("y2", function(d, i) { return yScale(plotdata[i+1][1]); })
```

to the following:

```// Line function which returns an X,Y pair for each point in our set, plus an interpolation method
// (more on the latter later).
var lineFunction = d3.svg.line()
.x(function(d) { return xScale(d[0]); })
.y(function(d) { return yScale(d[1]); })
.interpolate('linear');

// This is all we need to do to set up our path!
svg.append('svg:path')
.attr('d', lineFunction(plotdata))
```

Ah, one more thing — the fill attribute on a path element isn't just for show as it is with the line element! With a path it works the way you'd expect — it closes the path by drawing a line back to the starting point, and fills in the polygon created thereby. All we need to do is change

```.style('fill', "rgb(6, 120, 155)");
```

from our previous code to:

```.style('fill', "none");
```

There it is! Now we have a path which exactly matches what our previous line-based graph did, and in fewer lines of code.

## Smoothing Things Out

Look closely at the bottom left of the function graph — there's a "kink" at (1, 1) where the path segment from (0, 0) to (1, 1) meets the segment from (1, 1) to (2, 1.414). This is an artifact of the 'linear' interpolation method I chose above. It's more obvious if we change the function and the viewing window:

```var plotfunc = function(x) { return 1 + Math.sin(x); },
plotdata = [];
var lowX = 0, highX = 10, dX = 1;
```

Now that's ugly. Fortunately, changing the interpolation method used by d3 is simple: [2]

```var lineFunction = d3.svg.line()
.x(function(d) { return xScale(d[0]); })
.y(function(d) { return yScale(d[1]); })
.interpolate('basis');  // only this line was changed
```

## Wrapping Up

The full code for this exercise can be found here. We still need to change the x and y domains to be dynamic rather than hardcoded, and allow the user to graph arbitrary functions, so tune in next week for part 3!

### Footnotes

 [1] If you are interested in SVG's path mini-language, W3Schools has a quick reference, and Mozilla has a more in-depth tutorial.
 [2] A full list of interpolation methods with visual examples can be found at the bottom of this page.