To draw our graph, we first need some data to display. I already created an array of test data, but you could also fetch the data from a JSON endpoint or something similar instead.
Now that we have our data, we have to scale it. For this, we will import the first part of D3. We will import a scale linear from D3 scale. Now with the scale, you can create scale x which is a call to scale linear with a domain and range. The domain is the incoming data.
What do I expect for values that come into my graphs? In this case, we will just use the error indices so they will range from zero to data.length. The range specifies the pixel values that are used to draw the data on the graph. We will use a 500 pixel wide square graph.
Now we do the same for the y axis. We create a scale, scale y. Again, I call to scale linear with domain and range. Again, the domain is the incoming data, so we need a minimum and a maximum value of our data.
Those are quite easy to calculate. Our minimum value is simply math.min over the complete array, and our maximum is math.max over the complete array. The range as set we will use a square graph so again 0to 500 pixels.
Now that we have our scales, we can actually scale our data. We create a tuples variable, and we use the array.map function first to take the data and the index and simply put them as x and y coordinates into an array. Then we use map again, this time with the tuple. Now we can scale the tuple.
We call scale x with our x value and scale y with our y value. Now we can take a look at this data. We will simply console.log tuples. In the browser, we will see an array of 100 tuples, and we see that the data is already different than the original data.
We can confirm that it's working because we have 100 data points here, and we have 500 write graph. The x axis is already scaled with five. Now with our scale data, we want to draw our graph. For this, we will import another part of D3. We will import a line generator from D3 shape.
Now we can create our custom generator. For this, we will create a new generator that is a call to line. We then specify the x accessor. It will get the tuple. We want just the first of the two values, the x value. We then do the same for y.
Again, we get the tuple and we want to second one. Those two lines are not actually needed because they are the default access source of line. I will simply delete them. Now, we can create a line string that is simply a call to our generator with our scales data.
We can again take a look at this data. In the console, we see a string with m's numbers and Ls in there. Let's create this path element. We track left path element equals document.create element NS because a path does not live in a normal dom. It lives in the SVG names space. We specify that. Then of course the tag name which is simply path.
Then we have to set an attribute, and this time the d attribute because that's the control attribute. We simply pass in our line string. Now we can simply add the path element to the existing SVG in the dom. We tab square a selector. We get our SVG, and then append a new child which is the path element.
If we now hit save, we see something in the browser, but it doesn't look right. First of all, it is too small. This is because we lack styling. We will create a stylesheet. We simply increase the size of the SVG because we used 500 pixel earlier. We want a square graph. Both of them are 500 pixels. Save and reload.
Now we have a complete graph, but it's filled weirdly. For this, we specify our path, should have no fill. Now our complete graph is gone. This is because we have no stroke specified. We will say we want a stroke in black and a stroke width of three pixels. If we now reload, we have exactly the graph we expected to see.