# Negative Axes and Axes Positioning With d3.js

I am available for work right now, if you are interested then email me directly.

Up until now when I have been dealing with d3.js’s axes components, I have always kept the axes positive, i.e. both the x and y axes where showing values greater than 0.

I have been hacking around with this fun side project that takes the input of an algebraic expression and plots a graph for a sample range of values for x. You can checkout the source code here if you are interested.

Below is a screenshot of the end result:

It quickly became apparent that in order to show the curve of the expression properly, I would need to construct negative and positive x and y axes.

I have the following function below that constructs the data of x and y coordinates to plot the curve against which uses the excellent mathjs library to transform the string algebraic expression into a javascript function (line 2). I then create a sample range for `x` values ranging from `-10` to `11` and evaluate the `y` coordinate for each item in the range by applying the function on line 5 to each item:

Armed with this data, I can now construct my axes.

I first create the axis against a scale that is in proportion with the viewport dimensions.

The `domain` function of `d3` allows you to specify a minimum and maximum value as the range of values that we can use for a particular axis.

Below I am using d3’s `extent` function that returns the minum and maximum values of an array and is equivalent to calling `d3.min` and `d3.max` simultaneously.

As I am supplying the values for the range of `x` values in the code above, I know that I will always have negative `x` values and positive `x` values.

The y coordinates are different depending on the function generated from the algebraic expression. Depending on the expression, there are basically 3 conditions I want to capture when displaying a curve.

The first case is when there are only positive y values:

The next case is when there are both negative and positive y values;

Lastly, only negative y values:

With this in mind, the code below creates a domain based on the minimum values of y and the maximum values of y:

I either start my domain at `0` or use `d3.extent` again to get the maximum and minimum values for y like I did before for x.

The last problem to solve was to position the x axis. In the 3 code samples below, I am capturing the domain for y and the x axis position for each condition.

This is easy if I only have negative or positive values for `y`. I can simply place the `x` axis at the bottom for only positive values:

When I have only negative values, then I can place the x axis at the top of the document:

The interesting case was when I have both positive and negative values for `y`.

What I ended up doing was selecting all the ticks or labels from the y axis and finding the label that had `0` against it and from that I could use d3 to to select its position and then use that for my x axis position.

Below is the code that does that:

In the code above, I filter out all the other ticks apart from the `0` label. The zero tick is then passed into the `map` function which selects the transform attribute of the tick which might look something like this `translate(0,280)`. The second value of translate, `280` in this instance gives me the position of the `0` label in the y axis. I can use this value to position my x axis.

Once I have the position of 0 in the y axis, I can position the axis to the document:

When it comes to positioning the y axis, I simply divide the width by 2 and position it there:

I am available for work right now, if you are interested then email me directly.