Driving Usability With Empirical Data

Too often, I work with folks that dismiss many years of interface design and information architecture experience as "your opinion" and are eager to offer their own in place of good design practices. To avoid such "he said, she said" arguments (oh, and do the right thing for the user), I’m always happier when I’ve got some empirical data to guide my efforts when (re)designing my user interfaces.

First and foremost, data doesn’t lie. It’s often easier to champion a user interface change when there are charts, graphs, and statistics to back you up. Analyze the data and present it to stakeholders in a simple, straightforward way to support your decisions. To that end, prepare to be surprised. Sometimes the choice you thought was obvious isn’t the right one once you analyze the data.

The Requirement

As an advanced user, in order to find the best result from a set, I wish to filter the result set by metric A, a continuous variable between 0 and 1 inclusive, shown to the user as a percent value.

The Previous Implementation

A slider control was shown to users that allowed them to choose a value between 0% and 100% in 5% increments. Simple enough, but as I talked to users and examined the Google Analytics for the site, I found that very few users were using this filter. Why?

Analyzing the Data

Metric A is a great discriminator for our data set, so why weren’t users taking advantage of this filter? I grabbed a data set of 500,000 values from our production database and started my analysis. First, some summary statistics generated with R:

    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
0.000000 0.000000 0.006135 0.072020 0.098200 1.000000  

A basic histogram:

png('metricA_hist.png', width=600, height=400, units='px')
hist(d, breaks=seq(0,1,by=0.02), freq=TRUE, main='Metric A Distribution', xaxt='n', xlab='Value (%)')
axis(1, at=seq(0,1,by=0.2), labels=seq(0,100,by=20))
dev.off()

Metric A Histogram

And a density plot:

png('metricA_density.png', width=600, height=400, units='px')
den < - density(d)
plot(den, main='Metric A Density', xaxt='n', xlab='Value (%)')
polygon(den, col='skyblue')
axis(1, at=seq(0,1,by=0.2), labels=seq(0,100,by=20))
dev.off()

Metric A Density

Some observations:

  • The median value is less than 1%.
  • The interquartile range is just under 10%.
  • The remaining values drop off after 40%.

To keep things simple, we should let users filter with increased precision from 0% to 10%, and with less precision up to 40% or so.

The New Implementation

I’ve always been a fan of jQuery and its rich plugin community. For this project, I used noUiSlider, which has great mobile support, a clean/responsive interface, and good documentation. The implementation was as simple as:

$('#elem').noUiSlider({
    start: 0,
    range : {
        'min': [ 0, 0.01 ],
        '50%': [ 0.1, 0.05 ],
        'max': 0.50
    }
});

I’ve configured noUiSlider to use the first half of the slider to allow 1 percent increments from 0 to 10 percent, and use the second half of the slider to allow 5 percent increments from 15 to 50 percent. In doing so, I’ve distributed a total of 20 options equally along the slider range.

Visit http://refreshless.com/nouislider/examples/ to see it in action (scroll down to see the Non-linear slider example).

Hope that gives you some inspiration!

Christiaan

Leave a Reply