Having a nice, well-spaced graph is important, but it can sometimes be a little tricky.
A lot of d3 (and programmatic graphics work in general) is figuring out how position coordinates, canvas sizes and height/width relate. It’s simple algebra, but it can be tough to wrap your head around.
The Case of the Too Small Canvas
Let’s say we have a nice simple bar chart that spans the width of the container SVG. I’ve outlined the SVG to help us see where its bounds are.
But hey! We live in the future, and in the future we have labeled charts. So first thing we have to do is make a little room on the left hand side, by increasing the x value.
You can see the ‘Bananas’ bar go all the way to the right, and you just assume it ends at the end. Wrong! If you open up the web inspector…
Hey, look at that! It’s going over the edge, right off the svg canvas!
But let’s think about it: We added 60 pixels of padding to the left, but our bar still wants to be svg_width pixels wide. If the bar is starting 60 pixels in, it needs to be 60 pixels shorter than the width of the SVG. You can make that happen by adjusting the .range of the scale.
You could also create a variable called left_padding and use it in the scale and in the .attr('x', 60) section, but we’ll stick with that for now.
And if you go on and open up the web inspector to check it out…
Success! No longer runs over the edge.
The Case Of Axis Overflow
Let’s say we’re working with the same thing as above, but we’re also adding in an axis. Most of the time the labels are going to go riiiight off the end of the page.
We gotta get rid of that clipped 80! It’s super easy, though.
So, the length of the bar and the length of the axis are both determined by the same variable - scale. It’s going to stretch the banana bar and the axis out to the maximum range (80 sales, svg_width - 60 pixels).
All we gotta do is shorten the range to shorten the bar! Let’s chop another 20 pixels off.
Yes, svg_width - 60 - 20 is the same thing as svg_width - 80, but keeping them separate helps me remember what both numers are for! The 60 is to keep the bar from going off of the svg canvas from when we shifted the x, and the 20 is to pull it back a little from the right hand side.
Horizontal bars are easy! Your x stays at 0 (left hand side), and your y hops down the page to space the bars out, and your width is how big the bar is.
Vertical bars are another story! It isn’t tough, it’s just one of those things you need to realize before you Get It.
Let’s start with two bars. At the very least we know they need to be spaced out evenly left-to-right using x and their height is going to be how long they are.
As we know, we can only change the top left of the rect using x and y. For example, maybe we keep pushing it down until the first bar is grounded on the bottom of the svg.
Which lines up one of them, but not the others. In order to get the next bar down, we need to increase the y even further…
Which seems passable until you use the web inspector, and notice the longest bar is going outside of the canvas.
You probably already knew this, but it looks like you have to set each bar’s y individually to make things work. Every time you have to do something to each and every unit in a visualization, there’s always a formula waiting for you.
We just found out that a 60-pixel-long bar needs an offset of 20, and a 40-pixel-long bar needs 40. Let’s look at this for a second!
bar height
required y offset
added together
60
20
80
40
40
80
20
60
80
Hmmm… looks like “bar height” + “required y offset” always equals 80 (I cheated when I added that third column). If we take a closer look, 80 is the height of our svg!
It makes sense when you think about it - in order to draw a rectangles that touches the bottom of the svg, you need to start drawing from the height of the rectangle. If we want to get mathy, this means
bar height + required y offset = svg_size
which, since we’re looking to set y, means
required y offset = svg_size - bar height
which means *we need to use the formula for height in the formula for the y offset. If we cut out just that part…
And there we have it! Sometime we’ll need to size elements based on elements other than the containing SVG - maybe other elements or groupings or whatnot - so keep your eye out for these things!
Want to hear when I release new things? My infrequent and sporadic newsletter can help with that.