Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using D3 Scales to convert colour to number

I would like to have this colour scheme as my input domain: enter image description here

And a value between 0 and 1 as my output range. However, I am not sure which type of scale to use or how to add the scheme as an input domain.

The code below is the opposite of what I am trying to do.

let scaleSequential1 = d3.scaleSequential()
  .domain([0, 1])
  .interpolator(d3.interpolateViridis);

console.log( scaleSequential1(0) ); //#440154
console.log( scaleSequential1(0.5) ); //#21918c
console.log( scaleSequential1(1) ); //#fde725
like image 497
Ivan Bacher Avatar asked Mar 04 '23 21:03

Ivan Bacher


1 Answers

Following up on my comment, there is no direct way to do this. You can hack it up if you like this. If you are going to call it frequently I'd wrap in in a closure to spare the .map...

function invertViridis(color){
  return d3.range(0, 1.01, 0.01).map(i => d3.interpolateViridis(i)).indexOf(color) / 100;
}

console.log(invertViridis("#440154"));
console.log(invertViridis("#3b528b"));
console.log(invertViridis("#21918c"));
console.log(invertViridis("#5ec962"));
console.log(invertViridis("#fde725"));

function invertViridisClosure(){
  var r = d3.range(0, 1.01, 0.01).map(i => d3.interpolateViridis(i));
  return function(color) {
    return r.indexOf(color) / 100;
  }
}

let f = invertViridisClosure();
console.log(f("#440154"));
console.log(f("#3b528b"));
console.log(f("#21918c"));
console.log(f("#5ec962"));
console.log(f("#fde725"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
like image 145
Mark Avatar answered Mar 28 '23 04:03

Mark