I don't want to focus on the CSS code above or the data loading below.
For this example I only want to focus on the draw function.
If you're curious about what exactly the CSS or
the data loading functions were doing, I suggest reading
through Mike Bostock's tutorial, which is linked to in the instructor notes.
We have already seen many of the functions that Mike uses in his tutorial.
We have scales and range, select and attributes, a domain, and also .text.
The first two lines define the width for the chart and the height for the bars.
A second chunk of code here creates a linear scale and
sets the range to be zero to the width of our chart.
If you think about these values of zero and width, it makes perfect sense.
We don't want any of our data points to get placed past zero on our chart, or
in the negative region.
Nor do we want any data points to extend beyond the right
most edge of our chart.
A subtlety of this code here is that while I've labeled it
as the x-axis scale and while the variable of storing is x, there
is nothing specific to this code or its functions which define it as the x-axis.
We will see later that how we use it, however, creates the x values.
The third group of code sets the width on our SVG chart element.
If you remember we hard coded into the HTML an SVG element that had
the class chart.
So, here we're selecting that chart with d3.select and
then changing the width attribute to the width variable.
In this case, 420.
Keep in mind that this code corresponds to the blue bars I showed earlier, and
the blue bars extended from left to right horizontally according to
the value of the data.
On line 28 here the call to the domain method on X
has quite a lot of things going on with it.
First off, X was created above here as a linear scale.
Remember, however, what I said earlier about d3's chainable syntax.
Even though d3.scale.linear.range is a method call, it returns the scale object.
So x is actually a scale and not a range.
So this call here is actually calling domain on the scale of x.
The domain of our data represents the min and max of our data values.
You can see here that we simply hard code a value of 0 as
the minimum of our domain.
The d3 max function takes our data as the first argument and
a function to call on that data as a second argument.
Notice here that the function takes a single argument, d.
What gets passed to this function is actually every datum, so a single piece of
data, from our data array, and the function gets executed once for each.
So inside of this function,
d actually corresponds to a single data point and we get its value.
The reason we need to pass a function is that d3,
being the data-driven library it is,
could have different ways of defining the max of the domain for a given data.
So this function, passed as a second argument, allows a generalized max function
to work no matter what your data looks like or what the structure is.
Inside this function, you simply need to return whichever value from each
data point you want to use as the value to compare in the max calculation.
Notice also that we don't store the return value of x.domain in any variable.
This is because both domain and
range mutate the internal state of the scale object,
setting some properties on the object itself rather than returning a value.