9

セルの背景色がd3カラースケールによって決定されるヒートマップを実装しています。一部の値はカテゴリです。それらの値は、["6TH"、 "7TH"、 "5TH"、"4TH"]のようなN個の異なる任意の文字列タイプのカテゴリにすることができます。

開始色d3.rgb( "blue")と終了色d3.rgb( "red")が与えられた場合、文字列の個別のドメインを連続した色の範囲にマッピングするカラースケールを作成するにはどうすればよいですか?

私は試した

var scale = d3.scale.ordinal()
    .domain(["6TH", "7TH", "5TH", "4TH"])
    .rangeBands( [ d3.rgb("blue"), d3.rgb("red") ] );

これは明らかに機能しません。

4

3 に答える 3

31

まず、すぐに利用できるColorbrewerスケールの1つを使用することを検討します。colorbrewer2.orgを参照してください。これらは、D3のgitリポジトリでJavaScriptおよびCSSファイルとしても利用できます。lib/colorbrewerを参照してください。たとえば、ドメインに4つの個別の値があり、赤と青の発散スケールが必要な場合は、次のように言うことができます。

var color = d3.scale.ordinal()
    .domain(["6TH", "7TH", "5TH", "4TH"])
    .range(colorbrewer.RdBu[4]);

(これより前の場所も必要です<script src="colorbrewer.js"></script>。)Colorbrewerには、適切に設計されたさまざまなシーケンシャル、ダイバージ、およびカテゴリーのカラースケールがあります。

独自のカラースケールをローリングすることを主張する場合は、正確な知覚のためにL * a *b*またはHCL色空間で補間することを強くお勧めします。これは、 d3.interpolateLabまたはd3.interpolateHclを使用して実行できます。たとえば、d3.interpolateLab("red", "blue")(.5)赤と青の中間の色を返します。

順序スケールの範囲の色を計算するには、補間器を使用するか、一時的な線形スケールの方が便利な場合があります。例えば:

var categories = ["6TH", "7TH", "5TH", "4TH"];

var color = d3.scale.ordinal()
    .domain(categories)
    .range(d3.range(categories.length).map(d3.scale.linear()
      .domain([0, categories.length - 1])
      .range(["red", "blue"])
      .interpolate(d3.interpolateLab)));
于 2012-08-31T21:22:43.937 に答える
3

あなたは正しい考えを持っています、あなたはただ各R / G/Bカラーチャンネルを処理する必要があります。たとえば、バニラJavaScriptでは、次のことができます。

var a = [255, 0, 0], // First color
    b = [0, 0, 255], // Other color
    bands = 5,       // Bands is the length of your domain
    i, 
    delta = [];      // Difference between color in each channel

// Compute difference between each color
for (i = 0; i < 4; i++){
  delta[i] = (a[i] - b[i]) / (bands + 1);
}

// Use that difference to create your bands
for (i = 0; i <= bands + 1; i++){
  var r = Math.round(a[0] - delta[0] * i);
  var g = Math.round(a[1] - delta[1] * i);
  var b = Math.round(a[2] - delta[2] * i);
  console.log("<div style='background-color: #" + dec2hex(r) + dec2hex(g) + dec2hex(b) + "'>Band " + i + "</div>");
}

// A helper function for formatting
function dec2hex(i) {
  return (i+0x100).toString(16).substr(-2).toUpperCase();
}

d3のドキュメントによると、カラーオブジェクトの属性と属性を使用rして各カラーチャネルを抽出できます。gb

# d3.rgb(color)

指定されたカラー文字列を解析して、新しいRGBカラーを作成します。色が文字列でない場合は、文字列に強制されます。したがって、このコンストラクターを使用して、既存の色のコピーを作成したり、d3.hsl色をRGBに強制的に変換したりすることもできます。

..。

結果の色は、[0,255]の範囲の赤、緑、青の整数チャネル値として保存されます。チャネルは、返されたオブジェクトのr、g、およびb属性として使用できます。

したがって、上記の例の上部では、次のように言うことができます。

var myColor = d3.rgb("blue"),
    a = [myColor.r, myColor.g, myColor.b],
...

それは役に立ちますか?

于 2012-08-31T15:00:36.290 に答える
0

順序尺度と線形尺度はいつでも連鎖させることができます。

最初のスケールは離散値から定量化可能な値を作成し、2番目のスケールはこれらの値をカラースケールで補間します。

このようなもの:

// Your categories
var data = ["6TH", "7TH", "5TH", "4TH"],

  // Define ordinal to linear scale...
  ordinal = d3.scale.ordinal().domain(data).rangePoints([0, 1]),

  // ...and linear to color scale
  linear = d3.scale.linear().domain([0, 1]).range([d3.rgb("blue"), d3.rgb("red")]);

// Now define your artificial 'compound' scale
function scale(d) {
  return linear(ordinal(d));
}

// And then use it on your D3 code
d3.selectAll('div')
  .data(data)
  .enter()
  .append('div')
  .style('background', scale) // <- et voilà ;)
  .text(function(d) {
    return d;
  });
div {
  color: white;
  width: 3em;
  padding: 1em;
  margin: .2em
  text-align: center;
  font-family: Arial, Helvetica, sans-serif;
  font-weight: bold
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

于 2017-05-09T17:35:43.850 に答える