2016-12-29 15 views
1

D3を使用してカレンダーヒートマップを作成しています。カレンダーヒートマップ:クオンタイルを使用する代わりに各色の%の範囲を定義する方法

これは私の現在のコードです:

<!DOCTYPE html> 
<meta charset="utf-8"> 
<html> 
    <head> 
    <style> 
     rect.bordered { 
     stroke: #E6E6E6; 
     stroke-width:2px; 
     } 

     text.mono { 
     font-size: 10pt; 
     font-family: Consolas, courier; 
     fill: #000; 
     } 

     text { 
     font-family: Consolas, courier; 
     font-size:1.0em; 
     } 

     text.axis-workweek { 
     fill: #000; 
     } 

     text.axis-worktime { 
     fill: #000; 
     } 
    </style> 
    <script src="http://d3js.org/d3.v3.js"></script> 
    </head> 
    <body> 
    <div id="chart"></div> 
    </div> 
    <script type="text/javascript"> 
    var title=""; 
     var margin = { top: 90, right: 0, bottom: 80, left: 30 }, 
      width = 960 - margin.left - margin.right, 
      height = 900 - margin.top - margin.bottom, 
      gridSize = Math.floor(width/42), 
      legendElementWidth = gridSize*2, 
      buckets = 5, 
      colors = ["#c7e9b4","#41b6c4","#1d91c0","#225ea8"], // alternatively colorbrewer.YlGnBu[9] 
      days = ["1", "2", "3", "4", "5", "6", "7","8", "9", "10", "11", "12","13", "14", "15", "16", "17","18", "19", "20", 
"21", "22","23", "24", "25", "26", "27","28", "29", "30", "31"], 
      times = ["7:00", "8:00", "9:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00", "18:00", "19:00", "20:00", "21:00"]; 
      datasets = ["data.tsv"]; 

     var svg = d3.select("#chart").append("svg") 
      .attr("width", width + margin.left + margin.right) 
      .attr("height", height + margin.top + margin.bottom) 
      .append("g") 
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

     svg.append("text") 
     .attr("x",0) 
     .attr("y",-40) 
     .text(title); 

     var dayLabels = svg.selectAll(".dayLabel") 
      .data(days) 
      .enter().append("text") 
      .text(function (d) { return d; }) 
      .attr("x", 0) 
      .attr("y", function (d, i) { return i * gridSize; }) 
      .style("text-anchor", "end") 
      .attr("transform", "translate(-6," + gridSize/1.5 + ")") 
      .attr("class", function (d, i) { return ((i >= 0 && i <= 4) ? "dayLabel mono axis axis-workweek" : "dayLabel mono axis"); }); 

     var timeLabels = svg.selectAll(".timeLabel") 
      .data(times) 
      .enter().append("text") 
      .text(function(d) { return d; }) 
      .attr("x", function(d, i) { return i * gridSize * 2.1; }) 
      .attr("y", 0) 
      .style("text-anchor", "middle") 
      .attr("transform", "translate(" + gridSize/2 + ", -6)") 
      .attr("class", function(d, i) { return ((i >= 7 && i <= 16) ? "timeLabel mono axis axis-worktime" : "timeLabel mono axis"); }); 

     var heatmapChart = function(tsvFile) { 
     d3.tsv(tsvFile, 
     function(d) { 
      return { 
      day: +d.day, 
      hour: +d.hour, 
      value: +d.value 
      }; 
     }, 
     function(error, data) { 
      var colorScale = d3.scale.quantile() 
       .domain([0, buckets - 1, d3.max(data, function (d) { return d.value; })]) 
       .range(colors); 

      var cards = svg.selectAll(".hour") 
       .data(data, function(d) {return d.day+':'+d.hour;}); 

      cards.append("title"); 

      cards.enter().append("rect") 
       .attr("x", function(d) { return (d.hour - 7) * gridSize * 2.05; }) 
       .attr("y", function(d) { return (d.day - 1) * gridSize; }) 
       .attr("rx", 4) 
       .attr("ry", 4) 
       .attr("class", "hour bordered") 
       .attr("width", gridSize*2) 
       .attr("height", gridSize) 
       .style("fill", colors[0]); 

      cards.transition().duration(1000) 
       .style("fill", function(d) { return colorScale(d.value); }); 

      cards.select("title").text(function(d) { return d.value; }); 

      cards.exit().remove(); 

      var legend = svg.selectAll(".legend") 
       .data([0].concat(colorScale.quantiles()), function(d) { return d; }); 

      legend.enter().append("g") 
       .attr("class", "legend"); 

      legend.append("rect") 
      .attr("x", height) 
      .attr("y", function(d, i) { return legendElementWidth * (i-0.5); }) 
      .attr("width", gridSize/2) 
      .attr("height", legendElementWidth) 
      .style("fill", function(d, i) { return colors[i]; }); 

      legend.append("text") 
      .attr("class", "mono") 
      .text(function(d) { return "≥ " + Math.round(d) + "%"; }) 
      .attr("x", (height) + gridSize) 
      .attr("y", function(d, i) { return legendElementWidth*i; }); 

      legend.exit().remove(); 

     }); 
     }; 

     heatmapChart(datasets[0]); 

    </script> 
    </body> 
</html> 

そして、これが結果です:

enter image description here

は、どのように私は各色ごとに手動%の範囲を定義することができますか?特に、quantiles.data([0].concat(colorScale.quantiles()), function(d) { return d; })を使用するため、4%から52%の間に大きなギャップがあります。私は>0%>5%>10%>15%>20%>25%を設定したいと思います。

サンプルデータセット(data.tsv):

day hour value 
1 7 0 
1 8 22.6829268293 
1 9 24.3243243243 
1 10 23.3374766936 
1 11 21.8156028369 
1 12 21.8499851765 
1 13 22.1323529412 
1 14 19.8275862069 
1 15 20.4545454546 
1 16 23.7329042638 
1 17 23.1717337716 
1 18 20.1895734597 
1 19 22.7552275523 
1 20 22.6277372263 
1 21 19.7278911564 
2 7 0 
2 8 24.1124260355 
2 9 25.0368912936 
2 10 23.8484398217 
2 11 23.6625514403 
2 12 23.5748436925 
2 13 23.3272227315 
2 14 21.8181818182 
2 15 20.3499079189 
2 16 20.7635009312 
2 17 26.4220183486 
2 18 21.8934911243 
2 19 19.8433420366 
2 20 19.8614318706 
2 21 24.6031746031 

答えて

1

あなたは、しきい値スケールを使用することができます。彼らはあなたが任意のサブセットをマッピングすることができ除い

しきい値スケールは、スケールを量子化するために似ています範囲内の離散値へのドメイン入力ドメインは依然として連続しており、一連のしきい値に基づいてスライスに分割されています。入力領域は、通常、標本母集団の高さ(メートルで測定)など、視覚化したいデータの次元です。出力範囲は、典型的には、(文字列として表される)色のセットなど、所望の出力視覚化の次元である。

しかし、これに注意を払う:規模の範囲内の値の数がN + 1である場合はNよりも少ない場合、規模のドメイン内の値の数はNでなければなりません

ドメイン内の要素の場合、範囲内の追加値は無視されます。

var colorScale = d3.scale.threshold() 
    .domain([value1, value2, value3]) 
    .range(colors); 

が希望のパーセンテージを使用してこれらの値を設定します。

この

colors配列は4つの値を持っているとして、あなたのケースでは、ドメインが3つしか任意の値を持つことができる、ということを意味します。

+0

ありがとうございます。コードを更新しました。ヒートマップはうまく見えますが、凡例には> 0%と> NaN%の2つの値があります。var colorScale = d3.scale.threshold() \t \t .domain([5,10,15]) \tレンジ(色); \t。 – Dinosaurius

+0

凡例を作成するには、凡例を作成する必要があります。凡例を作成するには、凡例を作成する必要があります。別のコード!閾値スケールには 'quantiles()'はありません。そしてあなたの 'concat'はそれなしで無意味です。 –

+0

よろしいですか。私はこれを試しました: 'var legend = svg.selectAll("。legend ") .data(colorScale);'、しかし凡例はまったく消えます。いくつか例を挙げてください。 – Dinosaurius

関連する問題