Back to Contents Page

Advanced Techniques

Let's quickly revisit our scaling barchart from the first lesson, and make a small cosmetic change. Previously, the chart was annotated with numbers at the base of the bars, which was hard to see. We're going to quickly add some code to put the text adjacent to the end of the bars for readability, and to introduce the ability to place text.

To do this, our old code won't do. We need a proper container, with defined boundaries to display our code in. We're going to use an SVG, scalar vector graphics element. Using divs to draw things is very primitive, and only really useful as an example / learning tool. We write this like so:

var w = 100%
var h = 100%;
var svg = d3.select("barchart3")
    .append("svg")
    .attr("width", w)
    .attr("height", h)
        

Of course, we don't have to use w or h, but writing the numbers directly in to the code can create confusion for yourself and your partners! Especially if your codebase starts growing, you'll soon lose track of what all these "magic numbers" mean. We call them magic numbers because they do something, but without any context. It's better to set constants like width and height in a central place with context. Often you might use verbose (full) names, but with SVG it's often obvious that w and h are width and height, because we're dealing with co-ordinates all the time.

We're going to move away from our constraint that everything had to resize nicely to fit inside the layout of the page, and focus instead on writing high quality d3 code. The reason we're doing this is that as we move to using SVG tags over divs, resizing becomes a much more complicated issue. As we want to focus on d3, and not CSS, we're just going to assume a base width of 600. From now on we're setting our height to be relative to the amount of data, and generating the SVG using d3. The code we're using to write the bar chart is below!

var data= [3, 6, 22, 40, 30, 22];
var width = 600;
, barHeight = 30;

var x = d3.scale.linear()
        .domain([0, d3.max(data)])
        .range([0, width]);

var chart = d3.select.(".chart")
            .attr("width", width)
            .attr("height", barHeight * data.length);

var bar = chart.selectAll("g")
            .data(data)
            .enter().append("g")
            .attr("transform", function(d, i) { return "translate(0," + i * barHeight + ")"; });

bar.append("rect")
            .attr("width", x)
            .attr("height", barHeight - 1);

bar.append("text")
            .attr("x", function(d) { return x(d) - 3; })
            .attr("y", barHeight / 2)
            .attr("dy", ".35em")
            .text(function(d) { return d; });
        

Lots of code! Which gives us the lovely graphic below... well almost. We also used an inline style tag to color our SVG elements.

Let's run through this code. A lot of it is very formulaic, and you should become used to it after making a few visualizations yourself and elaborating on your project. There are a few new functionalities however, so we'll go through those one by one.

Hopefully you can see how this model is much, much more flexible than our previous model. I could create a huge chart of hundreds of items, and the code would still be able to display and position each one, along with its corresponding information. As the containing element is generated by our code, then the only limit is the containing dividers or sections that we use on our website.

For the rest of the lesson we want you to focus on applying these modifications and design rules to your project. You should also try and look up exactly what domains and ranges are, and how they relate to functions if you don't already know. They're very handy! In maths, they allow us to quantify what the expected behaviour of a function is, and what kind of results we can expect. For example, in adding whole numbers like 1, 2, 3, we expect the range of results to also be whole numbers which are positive. Though this seems like a simple conclusion, it has really incredible applications in terms of defining and limiting otherwise uncountable data, as well as being able to design safe, secure, and reliable software that works every time.

Author : Ben Ryves