skip to Main Content

I would like to be able to reproduce this legend with the d3 library, currently I have my own algorithm that does this operation for me, but I don’t know how it would be with d3. For example for this data array [
24.17,
24.58,
24.82,
24.91,
26.25,
28.04,
29.67,
32.06,
32.08,
32.4,
32.53,
32.58,
32.94,
33.89,
34.15,
34.84,
35.39,
37.64,
40.75,
42.31,
46.89
]

The output of 3 serious quantiles

enter image description here

The output of 4 serious quantiles

enter image description here

The output of 5 serious quantiles

enter image description here

What I really need is a function that by passing the data array and the number of quantiles (3,4 or 5) the output is that of the image, taking into account that for example 3 is a minimum, maximum and a value between minimum and maximum, in reality they are not 3 quantiles, they would be 2, this procedure would be the same for 4 or 5, and these would be the colors that would be in the range colorbase: rgb(231, 25, 32)colorLimit: rgb(245, 163, 166)

2

Answers


  1. I would rather to create a linear scale of colors like this:

    var data =  [ 24.17, 24.58, 24.82, 24.91, 26.25, 28.04, 29.67, 32.06, 32.08, 32.4, 32.53, 32.58, 32.94, 33.89, 34.15, 34.84, 35.39, 37.64, 40.75, 42.31, 46.89 ]
    var minValue = d3.min(data)
    var maxValue = d3.max(data)
    var minColor = "rgb(231, 25, 32)"
    var maxColor = "rgb(245, 163, 166)"
    const colorScale = d3
        .scaleLinear()
        .domain([maxValue,minValue])
        .range([maxColor,minColor])
    // then use this color scale to get colors for your legend
    console.log(colorScale(data[5])) // output: "rgb(233, 49, 55)"
    
    Login or Signup to reply.
  2. Basically you need to make the number of colours you require (according to the number of quantiles), and then feed them as input along with your data into a d3 quantileScale

    From there you can get the cutoff values and start making your legend. Later, use the quantile scale to generate the colours for each individual datum as necessary

    PS I should also point out there is a d3 legend library that will do this stuff with less work on your part, but hasn’t been maintained to the latest d3 versions (https://github.com/susielu/d3-legend). If you’re on d3 v5 or less it’ll be worth a look.

    // Make a colour scale between 2 colours and pick X colours evenly from it
    var numberOfQuantiles = 4;
    var colorScale = d3.scaleLinear([0, numberOfQuantiles - 1], ['red', 'blue']);
    var colors = d3.range(numberOfQuantiles).map((quantile, index) => {
      return colorScale(index);
    });
    
    // use those colours as input to the quantile scale along with your data
    var data = [4, 5, 10, 16, 23, 35, 128, 56, 100, 56, 23, 14, 45, 67, 12];
    var qs = d3.scaleQuantile()
      .domain(data)
      .range(colors);
    
    // q has the quintile cutoff values in (1 less then the number of quantiles / colours)
    var q = qs.quantiles();
    
    // make a string, you can do a better job here
    // thing to remember is the first and last only have one value to show
    var s = '';
    q.forEach((cutoff, i) => {
      s += "<span style='background: " + colors[i] + "'></span>";
      s += (i > 0) ? q[i - 1] + "-" : "<";
      s += cutoff; // cutoff = q[i]
    })
    // Last colour
    s += "<span style='background: " + colors[colors.length - 1] + "'></span>&gt;" + q[q.length - 1];
    
    d3.select("#output2").html(s);
    #output2>span {
      width: 40px;
      height: 20px;
      display: inline-block;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
    <div id='output2'>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search