# Harmonious HSL Color Interpolator

• D3.js
• Color theory
• Tool
• Personal project

… wait what? What does that even mean?

This is a tool to generate beautiful color palettes with colors that have an equal percieved difference in brightness.

### Ok, let’s take a few steps back …

When working with data visualisations there’s often a need to use colors to differentiate between various categories or values.

So what’s the big deal? Let’s have a quick look at the RGB color wheel:

You may notice that the colors at 4, 8 and 12 o’clock appear brighter than the ones in between. The different colors’ wavelengths make up their brightness or percieved brightness, so some colors appear brighter or darker than others even though physically the luminosity is equal.

Here’s a formula to calculate the apparent brightness: (Source: NBD Tech)

``````Brightness = sqrt( .241 R^2 + .691 G^2 + .068 B^2 )
``````

@[customImage]({“id”:“mike-bostock_wrs2k6.webp”,“alt”:“visual comparison between the three different rainbows: (HSL, HCL, Cubehelix)”})

When I learned that Mike Bostock had included the Cubehelix rainbow into his d3.js library, that’s when I decided that I wanted to create a tool for generating smooth color scales between two colors.

So in this tool, all you have to do is define your colors on either side of your scale and how many colors you’d want in between. The color scale gets conveniently printed out with their respective hex values for you to use in whatever application you need them.

### Code

Let’s first discuss the differences between `d3.interpolateRgb()` and `d3.interpolateCubehelixLong()`. Let’s say we want a scale between red and green, and find the color exactly in the middle.

First we need to define our scales:

``````const scale_cubehelix = d3.interpolateCubehelixLong('red', 'green')
const scale_rgb = d3.interpolateRgb('red', 'green')
``````

Then we print some values:

``````console.log(scale_cubehelix(0)) // red
console.log(scale_cubehelix(0.5)) // rgb(41, 64, 235)
console.log(scale_cubehelix(1)) // green

console.log(scale_rgb(0)) // red
console.log(scale_rgb(0.5)) // rgb(128, 64, 0)
console.log(scale_rgb(1)) // green
``````

As you can see, the `d3.interpolateRgb()` method has a much more ignorant way of determining the middle colour (128, 64, 0 is exactly in between 255, 0, 0 and 0, 128, 0), whilst `d3.interpolateCubehelixLong()` produces seemingly more random values.

Here’s a comparison between the `interpolateRgb()` on the left and the `interpolateCubehelixLong()` on the right:

And if we convert the colors to greyscale it’s apparent that the brightness is a lot smoother on the right side.