D3:将两个色标合并为一个

LBe*_*Bes 3 javascript colors d3.js

我目前有两个变量,我可以在两个颜色标度s1和s2上映射到两种不同的颜色.s1给出了红色的阴影,对应于我的变量X的值(4种不同的颜色).s1给出了对应于我的变量Y的值的蓝色阴影(也有4种不同的可能颜色).

现在我想得到的是允许我将这两者结合起来以获得变量组合的独特颜色.所以对于一对(X,Y),我在比例上得到一种颜色.所以我得到了16种颜色的比例.

这是一个传说,说明了我正在寻找的东西:

在此输入图像描述

我一直在寻找在线示例,但无法弄清楚如何实现这一目标.

And*_*eid 5

您可以将两个阈值比例相当容易地组合到一个新的比例函数中.该函数的核心可能如下所示:

d3.scaleBivariate = function() {
  function scaleBivariate(value) {
    var r = reds(value[0]);
    var b = blues(value[1]);

    return "rgb("+r+","+((r+b)/2)+","+b+")";
  }

  var blues = d3.scaleThreshold()
    .range([255,205,155,105,55])
    .domain([0,1,2,3,4,5]);

  var reds = d3.scaleThreshold()
    .range([255,205,155,105,55])
    .domain([0,1,2,3,4,5]);

  return scaleBivariate;

}
Run Code Online (Sandbox Code Playgroud)

这将借助两个d3阈值刻度设置红色和蓝色通道.绿色只是设置为两者之间的平均值,但您可以将其设置为任何所需的值,例如0或其他两个通道的最小值.我的红/蓝范围是任意的,也很容易改变.

以上可以用作:

d3.scaleBivariate = function() {
  function scaleBivariate(value) {
    var r = reds(value[0]);
    var b = blues(value[1]);

    return "rgb("+r+","+((r+b)/2)+","+b+")";
  }

  var blues = d3.scaleThreshold()
    .range([255,205,155,105,55])
    .domain([0,1,2,3,4,5]);
        
  var reds = d3.scaleThreshold()
    .range([255,205,155,105,55])
    .domain([0,1,2,3,4,5]);
        
  return scaleBivariate;

}

// Dummy data:
var data = d3.range(16).map(function(d) {
  return {x: d%4, y: Math.floor(d/4) }
})


var svg = d3.select("svg");
var size = 30;

var color = d3.scaleBivariate();

svg.selectAll("rect")
  .data(data)
  .enter()
  .append("rect")
  .attr("x", function(d) { return d.x * size })
  .attr("y", function(d) { return d.y * size })
  .attr("width",size)
  .attr("height",size)
  .attr("fill",function(d) {
    return color([d.x,d.y]);
  });
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.0.0/d3.min.js"></script>

<svg></svg>
Run Code Online (Sandbox Code Playgroud)

当然,您可能希望通过添加方法来添加一些灵活性,以修改哪些基准属性设置哪些颜色与哪些属性相关联,阈值应该是什么等.为了提供一个基本示例,下面的示例添加了用于设置属性的访问器应该映射到蓝色和红色通道:

d3.scaleBivariate = function() {

  function scaleBivariate(value) {
     var r = reds(red(value));
     var b = blues(blue(value));
     return "rgb("+r+","+((r+b)/2)+","+b+")";
  }
  
  var blues = d3.scaleThreshold()
    .range([255,205,155,105,55])
    .domain([0,1,2,3,4,5]);
    
  var reds = d3.scaleThreshold()
    .range([255,205,155,105,55])
    .domain([0,1,2,3,4,5]);
    
  var red = function(d) { return d[0]; }
  
  var blue = function(d) { return d[1];}
  
  // Accessors:
  scaleBivariate.red = function(_) {
    return arguments.length ? (red = _, scaleBivariate): red;
  }
  
  scaleBivariate.blue = function(_) {
    return arguments.length ? (blue = _, scaleBivariate): blue;  
  }
  
  return scaleBivariate;
}

var data = d3.range(16).map(function(d) {
  return {x: d%4, y: Math.floor(d/4) }
})

var svg = d3.select("svg");
var size = 30;

// set up the color scale:
var color = d3.scaleBivariate()
  .red(function(d) { return d.x; })
  .blue(function(d) { return d.y; });

svg.selectAll("rect")
  .data(data)
  .enter()
  .append("rect")
  .attr("x", function(d) { return d.x * size })
  .attr("y", function(d) { return d.y * size })
  .attr("width",size)
  .attr("height",size)
  .attr("fill",color);
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.0.0/d3.min.js"></script>

<svg></svg>
Run Code Online (Sandbox Code Playgroud)