Utility methods with d3-array

They're easy to overlook, but D3 includes an impressive set of utility functions for dealing with data. Defined in the d3-array repository and available on their own or as part of the library, they can be a valuable resource even outside of data viz projects.

Today we'll look at a few of these methods but I'd encourage you to at least skim the docs so you know what's there.

d3.min(array[, accessor])

d3.min, unsurprisingly, finds the minimum value in an array. Providing the optional accessor function is like calling array.map(accessor) before the comparisons are done, and is useful when your array contains objects. For example, if you wanted to find the student with the lowest score you could do something like this.

const students = [
    {name: 'Conor', score: 97},
    {name: 'Justin', score: 85},
    ...
    {name: 'Floyd', score: 62}
]
 
const flunkee = d3.min(
    students, 
    (student) => student.score
)

This is easier and much more clear than writing your own routine using Math.min and tracking the lowest value in a temp var. d3.min will also skip undefined, null, and NaN values, which are extremely common in real world, unsanitized data.

d3.max(array[, accessor])

Can you guess what this one does? Yea, I thought so.

d3.extent(array[, accessor])

d3.extent is like a shortcut for [d3.min(array), d3.max(array)], returning a two element array of the minimum and maximum values from the array. Does that sound familiar?

Yep, d3.extent returns an array perfect for passing to a scale's domain method. While it wouldn't work for something dimensional (you wouldn't want the lowest score's column height to be zero, for example), it can be great for results that fall on a spectrum. For example, maybe the lowest score should be red, the highest green, and everything in between gets something in between.

const colorScale = d3.scaleLinear()
  .domain(d3.extent(
    students, 
    (student) => student.score
  ))
  .range(['red', 'green'])
 
// then later...
.style('color', d => colorScale(d.score))

d3.sum, d3.mean, and d3.median

Not as common but occasionally useful, these methods do exactly what you'd expect. They also retain the same signature, accepting an array of data and an optional accessor method.

So much more

These really just scratch the surface of everything available in d3-array. From standard deviation to binary searches to sorting, there is a treasure trove of functions available. Even if you rarely or never use most of them, take a few minutes to browse the docs. If you're anything like me you'll feel a tiny bit smarter just having done that. 😄

Until next time!