Linear Scales


The previous lesson described the concept of scale in data visualization. Scales allow, for instance, to translate a value in our dataset to a position on the screen.

Now, let's study the most common scale type and its d3.js implementation: the linear scale and its scaleLinear() function.

Members only
5 minutes read
05060821000 px250 px500 px

The scaleLinear() function

The scaleLinear() function is part of the d3-scale module. It's probably the D3 function you'll use the most — and it solves the circle problem above perfectly!

Like d3.line() from the SVG module, scaleLinear() is a function that returns a function. And just like d3.line(), it uses method chaining to configure its behavior.

It expects two inputs: a domain and a range.

→ Domain

An array of two values: the min and max of your data. This is the "input" side — the world of your dataset (0 and 100 in the circle example).

→ Range

An array of two values: the start and end positions in pixels. This is the "output" side — the world of the screen (0 and 500 in the circle example).

The result is a function. Give it any value from the domain, and it returns the corresponding pixel position in the range.

Let's create a scale to fix the green circles above:

// Import the function from d3
import { scaleLinear } from "d3";

// Create a scale
// Data goes from 0 to 100, screen goes from 0 to 500px
const scale = scaleLinear()
  .domain([0, 100])   // input: data values
  .range([0, 500]);   // output: pixel positions

// Use it! 82 in the data → 410px on screen
console.log(scale(82));
// 410

Fixing the circles

Now let's use scaleLinear() to fix the green circles from the exercise above. The full process is: data → scale → SVG.

We loop over the data with .map() and call the scale for each circle to compute its cx position. The scale is the bridge between a data value and a pixel position.

import { scaleLinear } from "d3";

// 1️⃣ The data: same values as the exercise above
const data = [0, 50, 60, 82, 100];

const width = 500;
const height = 80;

export default function App() {
  // 2️⃣ Create a scale: data (0–100) → pixels (0–500)
  const xScale = scaleLinear()
    .domain([0, 100])    // input: data values
    .range([0, width]);  // output: pixel positions

  // 3️⃣ Render: call xScale() for each circle's cx position
  return (
    <svg width={width} height={height}>
      {data.map((value, i) => (
        <circle
          key={i}
          cx={xScale(value)}  // data value → pixel position
          cy={height / 2}     // all circles on the same line
          r={16}
          fill="#69b3a2"
        />
      ))}
    </svg>
  );
}

Try changing a value in the data array — the circle moves automatically. The scale handles the translation for you.

Oh no! 😱

This lesson isn’t available just yet.

Take a look at the status badges next to each lesson in the sidebar to see when it’s coming out.

Thanks for your patience! 🙏