Using .attr and .style

Once upon a time there were <rect>s, and <rect>s were good.

Open example in new window

<svg height="60" width="120">
  <rect></rect>
  <rect></rect>
  <rect></rect>
</svg>

Open example in new window

All of these rects are very very very boring, though. So boring, in fact, that you can’t even see them.

The Joys of Attributes

The three rects above exist, but in the kind of way that your Aunt Mary’s baby exists in the months before it’s born. It’s kind of there, but you can’t see it and it sure as hell can’t do anything.

Babies need to be born and grow hair and get jobs and wear button-up shirts and stuff, and so does a rect! A rect can do that by getting an x and a y and width and a height.

Open example in new window

<svg height="60" width="120">
  <rect width="100" height="10" x="5" y="5"></rect>
  <rect width="10" height="20" x="25" y="25"></rect>
  <rect width="10" height="10" x="95" y="25"></rect>
</svg>

Open example in new window

These are all called attributes. Clothes make the manatee, and attributes make the shape! The x and y attributes position the rect inside of the svg, and the width and height give it a size.

Attributes are anything that gets an equals sign in the HTML. class can be an attribute, id can be an attribute. height and width are also attributes for svg, in case you didn’t notice!

Every kind of svg element has its own set of attributes. Sometimes they overlap, sometimes they don’t.

  • circle gets cx and cy for position, and r for radius
  • rect gets x and y for the top left, and width and height for its size
  • text gets x and y to position it and text-anchor to figure out how it gets aligned (centered, left-aligned, etc)

Those are just a few common ones, follow the links above to learn about other attributes. You can also check out a ton of other SVG elements.

By adding attributes to a rect or any other SVG element, you bring it to life. Two big things that attributes are for are

  • Position your element
  • Set your element’s size

Attributes in d3

Attributes in d3 are edited using .attr(). Let’s say we had the following svg:

<svg height="60" width="120">
  <rect width="10" x="10"></rect>
  <rect width="10" x="40"></rect>
  <rect width="10" x="70"></rect>
</svg>

It would look a lot like this:

Which is to say, like nothing, but it has no height or y! Don’t worry, though we can salvage the situation with d3.

After you select your elements, using .attr allows you to set an attribute to a specific value.

d3.selectAll("rect").attr('height', 20).attr('y', 30);

That code will set all of the rectangles to have a height of 20 and a y of 30.

NOTE: x, y, cx, and cy all position the elements inside of their parent SVG. The y is how far from the top, the x is how far from the left.

For the full example of not setting all of the attributes and then setting them later with d3, see below.

Open example in new window

<svg height="60" width="120">
  <rect width="10" x="10"></rect>
  <rect width="10" x="40"></rect>
  <rect width="10" x="70"></rect>
</svg>
<script>
  d3.selectAll("rect").attr('height', 20).attr('y', 30)
</script>

Open example in new window

But those are ugly, right? How about we spice them up?

The Joys of Styling

There’s another attribute we haven’t talked about, and it’s called style. It’s a way of writing CSS, all crammed into one line. For example:

Open example in new window

<svg height="60" width="120">
  <rect width="10" x="10" height="20" y="15" style="fill: red;"></rect>
  <rect width="10" x="40" height="20" y="15" style="fill: green;"></rect>
  <rect width="10" x="70" height="20" y="15" style="fill: blue;"></rect>
</svg>

Open example in new window

You can even add multiple CSS rules inside of the style attribute! You might even need to scroll to the right inside of the box below.

Open example in new window

<svg height="60" width="120">
  <rect width="10" x="10" height="20" y="15" style="fill: red; stroke-width: 2; opacity: 0.5;"></rect>
  <rect width="10" x="40" height="20" y="15" style="fill: green; stroke-width: 3; opacity: 0.75;"></rect>
  <rect width="10" x="70" height="20" y="15" style="fill: blue; stroke-width: 0.5; opacity: 0.2;"></rect>
</svg>

Open example in new window

The thing is, you’ll never do that. It’s pure garbage. It’s practically illegal. Never do that. If you want to write your own CSS, do it the Real Way, up in a <style> tag.

<style>
  rect {
    fill: red;
    opacity: 0.5;
    stroke-width: 3;
  }
</style>

But yeah, come on, we’re here to write d3! And because styling is very very very connected to the data you’re displaying (high danger? red!), we’re going to use d3 to edit the style tag. But there’s a catch.

Styling in d3

Even though style is an attribute, you don’t edit style using attr! Because so many different things can be hiding inside of style - maybe the stroke width, or the fill, or the opacity, etc - it gets its very own method, .style().

When you use style, the first parameter is the attribute you want to edit, and the second parameter is the value you’d like it to be. Sometimes the second parameter is a function!

HTML

<svg height="60" width="120">
  <rect width="10" x="10" height="20" y="30"></rect>
  <rect width="10" x="40" height="20" y="30"></rect>
  <rect width="10" x="70" height="20" y="30"></rect>
</svg>

JavaScript

d3.selectAll("rect").style('fill', 'red');

Result

Chances are you’ll be spending a lot of time changing the fill color using a function instead. That sets it piece by piece, looking at the associated piece of data.

JavaScript

var data = [1, 2, 3];
d3.selectAll("rect")
  .style('fill', function(d) {
    if(d >= 2) {
      return 'red';
    } else {
      return 'green';
    }
  });

Result

And there you have it!

Overlap between .attr and .style

Sometimes you have attributes that can also be styles. For example, text-anchor is used to align svg text, and you can use either .attr() or .style() with it!

Generally, though - position and size are .attr, and all other decoration is .style. But hey, that’s probably a lie, too.

Want to hear when I release new things?
My infrequent and sporadic newsletter can help with that.