21

我正在尝试为热图创建线性色标。我想对颜色进行缩放以通过大量特定颜色,其中第一种颜色对应于数据的最小值,最后一种颜色应赋予数据的最大值。

我知道我可以通过在最小值和最大值之间给出域 17 值来做到这一点,但是如果用户能够更改数据集(从而更改热图的颜色),我不知道如何动态执行此操作

本质上我想跟随,但我知道它不起作用

var colorScale = d3.scale.linear()
   .range(["#6363FF", "#6373FF", "#63A3FF", "#63E3FF", "#63FFFB", "#63FFCB",
           "#63FF9B", "#63FF6B", "#7BFF63", "#BBFF63", "#DBFF63", "#FBFF63", 
           "#FFD363", "#FFB363", "#FF8363", "#FF7363", "#FF6364"])
   .domain([d3.min(dataset, function(d) {return d;}),
            d3.max(dataset, function(d) {return d;})]);

谁能告诉我我需要在“域”中添加什么才能使其正常工作?

编辑:我确实找到了我想要的东西。使用 RI 使用 Designer.colors 函数从上面计算出 17 种颜色之间的 256 种颜色,并将其放入范围内。这确实给人一种连续色阶的感觉

var colorScale = d3.scale.linear()
    .range(["#6363FF", "#6364FF", "#6364FF", "#6365FF",
            "... several other lines with color codes ..."
            "#FF6764", "#FF6564", "#FF6464", "#FF6364"])
    .domain(d3.range(1,257));

var quantize = d3.scale.quantile()
   .range(d3.range(1,257))
   .domain([d3.min(dataset, function(d) {return d;}), 
            d3.max(dataset, function(d) {return d;})]);

现在我可以以这种方式使用颜色

colorScale(quantize(dataset))

但我想知道这是否也可以用更少的代码行来完成?

4

3 回答 3

29

你想把问题分开。首先为您的热图定义一个比例,将 0-1 映射到您的颜色。然后定义第二个(动态)比例,将您的数据集映射到 0-1。然后,您可以结合比例来绘制您的形状。

var colours = ["#6363FF", "#6373FF", "#63A3FF", "#63E3FF", "#63FFFB", "#63FFCB",
               "#63FF9B", "#63FF6B", "#7BFF63", "#BBFF63", "#DBFF63", "#FBFF63", 
               "#FFD363", "#FFB363", "#FF8363", "#FF7363", "#FF6364"];

var heatmapColour = d3.scale.linear()
  .domain(d3.range(0, 1, 1.0 / (colours.length - 1)))
  .range(colours);

// dynamic bit...
var c = d3.scale.linear().domain(d3.extent(dataset)).range([0,1]);

// use the heatmap to fill in a canvas or whatever you want to do...
canvas.append("svg:rect")
  .data(dataset)
  .enter()
  // snip...
  .style("fill", function(d) {
     return heatmapColour(c(d));

另外,您可以使用 d3.extent 函数一次性获取数据集的最小值和最大值。

于 2013-07-16T09:24:12.483 回答
4

使用定量标度Color Brewer

// pick any number [3-9]
var numColors = 9;

var heatmapColour = d3.scale.quantize()
  .domain(d3.extent(dataset))
  .range(colorbrewer.Reds[numColors]);

// use the heatmap to fill in a canvas or whatever you want to do...
canvas.append("svg:rect")
  .data(dataset)
  .enter()
  // snip...
  .style("fill", function(d) {return heatmapColour(d);})
于 2014-10-20T21:57:19.717 回答
3

使用阈值尺度。这是一个简单的例子:

coffee> d3 = require 'd3'
coffee> color = d3.scale.threshold().domain([5,30,100]).range(["red","orange","green"]);
coffee> color 6
'orange'
coffee> color 3
'red'
coffee> color 33
'green'
于 2014-02-21T11:18:55.760 回答