在d3 sequential.interpolator中,是否可以只使用一部分频谱?

时间:2018-04-05 15:13:00

标签: d3.js colors

在d3 sequential.interpolator中,是否可以仅使用一段光谱而不是全范围?看起来这样的调色板只需要输入域而不是范围,想知道是否可以指定某些东西只能占据色谱的中间或下部。感谢。

1 个答案:

答案 0 :(得分:1)

如果您不想创建自定义插补器,您可以通过两种方式实现所需的效果:

  • 修改域名,
  • 更改插值器的t计算方式。

如果您将域分配给具有两倍于数据实际域范围的比例,那么您将只使用一半的颜色范围。

但是,我将在这里扩展第二个,因为它允许您轻松修改比例类型。插值器的t参数是0到1之间的值:

  

给定范围[0,1]中的数字t,返回相应的颜色   来自...方案表示为RGB字符串。 (from the API docs)。

我们可以通过几种方式操纵t,以便我们只使用颜色渐变的一部分。例如,要仅显示渐变的前半部分的颜色,我们可以确保t永远不会超过0.5:

var truncated = d3.scaleSequential(function(t) {    
     return d3.interpolateViridis((t/2)) })
  .domain([1,10]);

或者得到中间:

var middle = d3.scaleSequential(function(t) {
    return d3.interpolateViridis(t/2+0.25) })
  .domain([1,10]);

如果使用t*2之类的内容,超过1或低于0的值将显示为极端值。

你也可以通过使用平方根或t的其他幂来做偏斜颜色,这在处理非线性数据时可能很有用。

var scale = d3.scaleSequential(d3.interpolateViridis)
   .domain([1,10]); 

var truncated = d3.scaleSequential(function(t) {    
     return d3.interpolateViridis((t/2)) })
  .domain([1,10]);
  
var middle = d3.scaleSequential(function(t) {
    return d3.interpolateViridis(t/2+0.25)
})
  .domain([1,10]);

var data = d3.range(10);

var svg = d3.select("body")
  .append("svg");
  
svg.selectAll(null)
  .data(data)
  .enter()
  .append("rect")
  .attr("width", 10)
  .attr("height", 10)
  .attr("x", function(d) { return d * 12 + 12; })
  .attr("y", 20)
  .attr("fill", function(d) { return scale(d); })
  
svg.selectAll(null)
  .data(data)
  .enter()
  .append("rect")
  .attr("width", 10)
  .attr("height", 10)
  .attr("x", function(d) { return d * 12 + 12; })
  .attr("y", 32)
  .attr("fill", function(d) { return truncated(d); })
  
svg.selectAll(null)
  .data(data)
  .enter()
  .append("rect")
  .attr("width", 10)
  .attr("height", 10)
  .attr("x", function(d) { return d * 12 + 12; })
  .attr("y", 44)
  .attr("fill", function(d) { return middle(d); })
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>