DEV Community

Sai Kiran
Sai Kiran

Posted on • Updated on

D3js fundamentals Part 4 Scales

Last article we learnt about path data.


As I wrote in the last article, it is not necessary to learn about the path data if you want to learn d3js, you can skip that part as it sometimes become too confusing to pickup the concepts and it just helps you in understanding what goes on in the background when you make a path.

If you see in this example, We have used data to match our svg width and height, like we used data 100,100 to start from point 100,100 of the svg but we will never be getting data that can match. Some data may be in floating point , some may be in long int, some in date format etc. Here comes the Scales in d3js to solve this problem. D3js have some neat features to play with data.

Lets see the simplest example

d3.scaleLinear()

In the above example we converted marks to percentages, simply means we took a range of values and fitted it into 0 to 100 range. This we use to fit our range of data, fit into width or height range of the svg. Look at this example

We took a different set of data that wouldn't fit in our svg and then scaled it to fit in.

This is our data

let data = [
       {x:-60,y:1120},
       {x:50,y:400},
       {x:160,y:220},
       {x:190,y:280},
       {x:330,y:360},
       {x:420,y:80},
       {x:560,y:560},
       {x:620,y:120},
       {x:930,y:700},
       {x:1120,y:-60}
     ]

In the previous article example we have just passed the data directly to the line generator but in this example our data is very different, so we have to define accessor to the line generator for x and y values like this

let lineGenerator = d3.line()
                      .x(d => d.x)
                      .y(d => d.y) 

Line generator will loop through the data array to get x and y values as returned by the accessor function .x(d => d.x).y(d => d.y) and then generate path data. In order to fit in the data to svg, data needs to scaled accordingly. We have to scale it before it gets passed to the x and y values.
First we initialize the scale by passing the smallest and largest value to domain and 0 to width or height of the svg to range, when the value gets passed it return the appropriate points on the svg.
Lowest point in our svg is -60 and largest value is 1120 which can be passed to domain and svg width is 500px which can be passed to range.

let scale = d3.scaleLinear()
                      .domain([-60, 1120])
                      .range([0, 500])

and convert data

let lineGenerator = d3.line()
                      .x(d => scale(d.x))
                      .y(d => scale(d.y))

We can get min and max values of the given data with the help of d3.extent(data, accessor), it will return an array. To get single minimum or maximum value use d3.min(data,accessor) and d3.max(data,accessor). You can know more about the array method in d3js here d3-array

There are 12 types of scaling in d3js which are classified into 3 types

  1. Continuous input and continuous output
  2. Continuous input and discrete output
    • d3.scaleQuantize()
    • d3.scaleQuantile()
    • d3.scaleThreshold()
  3. Discrete input and discrete output
    • d3.scaleOrdinal()
    • d3.scaleBand()
    • d3.scalePoint()

You can learn about them here d3-scale

Top comments (0)