Skip to content

Instantly share code, notes, and snippets.

@jsoma
Last active February 20, 2024 03:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jsoma/71bee11bbe6b73887bca4138fd4d2442 to your computer and use it in GitHub Desktop.
Save jsoma/71bee11bbe6b73887bca4138fd4d2442 to your computer and use it in GitHub Desktop.
How to understand the margin convention and axes in d3+svg

How to understand the margin convention and axes in d3+svg

This walkthrough uses Homework 5: Question 10 as a base, but if you're just a random person from the internet it might still make sense

Let's say we do the totally normal height = and width = thing, and the totally normal svg = d3.select thing.

var height = 400
var width = 400

var svg = d3
  .select('#chart10')
  .append('svg')
  .attr('height', height)
  .attr('width', width)

This puts an SVG inside of #chart10, and sets the svg to have a width of 400 and a height of 400.

Very nice.

...except not very nice, because it doesn't have any axes and the circles are going off of the side!

Oh well, let's just use the cut-and-paste axis command from snippets.txt. You'll use this exact code almost every single time you need axes.

var yAxis = d3.axisLeft(yPositionScale)
svg
    .append('g')
    .attr('class', 'axis y-axis')
    .call(yAxis)

var xAxis = d3.axisBottom(xPositionScale)
svg
    .append('g')
    .attr('class', 'axis x-axis')
    .attr('transform', 'translate(0,' + height + ')')
    .call(xAxis)

It goes at the bottom of the ready function, right after you've done all of your svg.selectAll/enter/append stuff to add the circles.

We add it, and tada! We have...

...a suspicious line on the left-hand side. And nothing else? Weird, 'eh? Let's use the inspector on it.

It turns out there's something on the left-hand side and something underneath, we just can't see them because they're outside of the SVG's drawing area (the grey space).

The way to fix this is to use something called the MARGIN CONVENTION.

The margin convention replaces a bunch of your code at the top of the page, the spot where we (up above) made the height and width and svg. You change it all to this code here:

  var margin = { top: 50, left: 50, right: 50, bottom: 50 }

  var height = 400 - margin.top - margin.bottom
  var width = 400 - margin.left - margin.right

  var svg = d3
    .select('#chart10')
    .append('svg')
    .attr('height', height + margin.top + margin.bottom)
    .attr('width', width + margin.left + margin.right)
    .append('g')
    .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')

Once we've changed it, suddenly our graphic looks reasonable and nice:

Now our total width is still 400 pixels, but there's a bit of a margin around where the graphic is drawn. 50 pixels on the top, left, bottom, and right.

This area - width minus the padding - is our drawing area for the graphic. The axes wind up outside of that.

Your width variable is now the actual drawing width (not 400), and 0,0 is the top left of the graphic area, not of the entire SVG.

It's SVG magic that we'll explore a little bit more later. For now, just accept this as the truth and reality of the situation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment