2016-12-27 8 views
0

カレンダーヒートマップを作成しましたが、「4500を超える」ブレーキに該当するデータは、指定された色#3d3768の代わりに黒でマークされるという問題があります。このカテゴリの色が見つからないようです。どうして?カレンダーヒートマップ:色が割り当てられていません

<!DOCTYPE html> 
<meta charset="utf-8"> 
<head> 
<title>Data Calendar</title> 
<style> 
    .month { 
     fill: none; 
     stroke: #000; 
     stroke-width: 2px; 
    } 
    .day { 
     fill: #fff; 
     stroke: #ccc; 
    } 
    text { 
     font-family:sans-serif; 
     font-size:1.5em; 
    } 
    .dayLabel { 
     fill:#aaa; 
     font-size:0.8em; 
    } 
    .monthLabel { 
     text-anchor:middle; 
     font-size:0.8em; 
     fill:#aaa; 
    } 
    .yearLabel { 
     fill:#aaa; 
     font-size:1.2em; 
    } 

    .key {font-size:0.5em;} 

</style> 
</head> 
<body> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script> 
<script> 

var breaks=[1500,2500,3500,4500,4550]; 
var colours=["#e2dff1","#b7b1dd","#8b82c8","#584f95","#3d3768"]; 

    //general layout information 
    var cellSize = 17; 
    var xOffset=20; 
    var yOffset=60; 
    var calY=50;//offset of calendar in each group 
    var calX=25; 
    var width = 960; 
    var height = 163; 
    var parseDate = d3.time.format("%d/%m/%y").parse; 
    format = d3.time.format("%d-%m-%Y"); 
    toolDate = d3.time.format("%d/%b/%y"); 

    d3.csv("data.csv", function(error, data) { 

     //set up an array of all the dates in the data which we need to work out the range of the data 
     var dates = new Array(); 
     var values = new Array(); 

     //parse the data 
     data.forEach(function(d) { 
       dates.push(parseDate(d.date)); 
       values.push(d.value); 
       d.date=parseDate(d.date); 
       d.value=d.value; 
       d.year=d.date.getFullYear();//extract the year from the data 
     }); 

     var yearlyData = d3.nest() 
      .key(function(d){return d.year;}) 
      .entries(data); 

     var svg = d3.select("body").append("svg") 
      .attr("width","90%") 
      .attr("viewBox","0 0 "+(xOffset+width)+" 540") 

     //title 
     svg.append("text") 
     .attr("x",xOffset) 
     .attr("y",20) 
     .text(title); 

     //create an SVG group for each year 
     var cals = svg.selectAll("g") 
      .data(yearlyData) 
      .enter() 
      .append("g") 
      .attr("id",function(d){ 
       return d.key; 
      }) 
      .attr("transform",function(d,i){ 
       return "translate(0,"+(yOffset+(i*(height+calY)))+")"; 
      }) 

     var labels = cals.append("text") 
      .attr("class","yearLabel") 
      .attr("x",xOffset) 
      .attr("y",15) 
      .text(function(d){return d.key}); 

     //create a daily rectangle for each year 
     var rects = cals.append("g") 
      .attr("id","alldays") 
      .selectAll(".day") 
      .data(function(d) { return d3.time.days(new Date(parseInt(d.key), 0, 1), new Date(parseInt(d.key) + 1, 0, 1)); }) 
      .enter().append("rect") 
      .attr("id",function(d) { 
       return "_"+format(d); 
       //return toolDate(d.date)+":\n"+d.value+" dead or missing"; 
      }) 
      .attr("class", "day") 
      .attr("width", cellSize) 
      .attr("height", cellSize) 
      .attr("x", function(d) { 
       return xOffset+calX+(d3.time.weekOfYear(d) * cellSize); 
      }) 
      .attr("y", function(d) { return calY+(d.getDay() * cellSize); }) 
      .datum(format); 

     //create day labels 
     var days = ['Su','Mo','Tu','We','Th','Fr','Sa']; 
     var dayLabels=cals.append("g").attr("id","dayLabels") 
     days.forEach(function(d,i) { 
      dayLabels.append("text") 
      .attr("class","dayLabel") 
      .attr("x",xOffset) 
      .attr("y",function(d) { return calY+(i * cellSize); }) 
      .attr("dy","0.9em") 
      .text(d); 
     }) 

     //let's draw the data on 
     var dataRects = cals.append("g") 
      .attr("id","dataDays") 
      .selectAll(".dataday") 
      .data(function(d){ 
       return d.values; 
      }) 
      .enter() 
      .append("rect") 
      .attr("id",function(d) { 
       return format(d.date)+":"+d.value; 
      }) 
      .attr("stroke","#ccc") 
      .attr("width",cellSize) 
      .attr("height",cellSize) 
      .attr("x", function(d){return xOffset+calX+(d3.time.weekOfYear(d.date) * cellSize);}) 
      .attr("y", function(d) { return calY+(d.date.getDay() * cellSize); }) 
      .attr("fill", function(d) { 
       if (d.value<breaks[0]) { 
        return colours[0]; 
       } 
       for (i=0;i<breaks.length+1;i++){ 
        if (d.value>=breaks[i]&&d.value<breaks[i+1]){ 
         return colours[i]; 
        } 
       } 
       if (d.value>breaks.length-1){ 
        return colours[breaks.length] 
       } 
      }) 

     //append a title element to give basic mouseover info 
     dataRects.append("title") 
      .text(function(d) { return toolDate(d.date)+":\n"+d.value+units; }); 

     //add montly outlines for calendar 
     cals.append("g") 
     .attr("id","monthOutlines") 
     .selectAll(".month") 
     .data(function(d) { 
      return d3.time.months(new Date(parseInt(d.key), 0, 1), 
            new Date(parseInt(d.key) + 1, 0, 1)); 
     }) 
     .enter().append("path") 
     .attr("class", "month") 
     .attr("transform","translate("+(xOffset+calX)+","+calY+")") 
     .attr("d", monthPath); 

     //retreive the bounding boxes of the outlines 
     var BB = new Array(); 
     var mp = document.getElementById("monthOutlines").childNodes; 
     for (var i=0;i<mp.length;i++){ 
      BB.push(mp[i].getBBox()); 
     } 

     var monthX = new Array(); 
     BB.forEach(function(d,i){ 
      boxCentre = d.width/2; 
      monthX.push(xOffset+calX+d.x+boxCentre); 
     }) 

     //create centred month labels around the bounding box of each month path 
     //create day labels 
     var months = ['JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC']; 
     var monthLabels=cals.append("g").attr("id","monthLabels") 
     months.forEach(function(d,i) { 
      monthLabels.append("text") 
      .attr("class","monthLabel") 
      .attr("x",monthX[i]) 
      .attr("y",calY/1.2) 
      .text(d); 
     }) 

     //create key 
     var key = svg.append("g") 
      .attr("id","key") 
      .attr("class","key") 
      .attr("transform",function(d){ 
       return "translate("+xOffset+","+(yOffset-(cellSize*1.5))+")"; 
      }); 

     key.selectAll("rect") 
      .data(colours) 
      .enter() 
      .append("rect") 
      .attr("width",cellSize) 
      .attr("height",cellSize) 
      .attr("x",function(d,i){ 
       return i*130; 
      }) 
      .attr("fill",function(d){ 
       return d; 
      }); 

     key.selectAll("text") 
      .data(colours) 
      .enter() 
      .append("text") 
      .attr("x",function(d,i){ 
       return cellSize+5+(i*130); 
      }) 
      .attr("y","1em") 
      .text(function(d,i){ 
       if (i<colours.length-1){ 
        return "up to "+breaks[i] + "%"; 
       } else { 
        return "over "+breaks[i-1] + "%"; 
       } 
      }); 

    });//end data load 

    //pure Bostock - compute and return monthly path data for any year 
    function monthPath(t0) { 
     var t1 = new Date(t0.getFullYear(), t0.getMonth() + 1, 0), 
      d0 = t0.getDay(), w0 = d3.time.weekOfYear(t0), 
      d1 = t1.getDay(), w1 = d3.time.weekOfYear(t1); 
     return "M" + (w0 + 1) * cellSize + "," + d0 * cellSize 
      + "H" + w0 * cellSize + "V" + 7 * cellSize 
      + "H" + w1 * cellSize + "V" + (d1 + 1) * cellSize 
      + "H" + (w1 + 1) * cellSize + "V" + 0 
      + "H" + (w0 + 1) * cellSize + "Z"; 
    } 

</script> 
</body> 
</html> 
+0

、なぜあなたは 'breaks.length + 1 'を反復していますか? – epascarello

+0

@epascarello:それに気づいてくれてありがとう。私は 'i = 0; i Dinosaurius

答えて

0

あなたの色選択コードはいくらかサイズを小さくすることができます。また、d3スケールを使用して色を選択すると、これももっときれいになります。しかし、最終的には、あなたの問題はここにある:

  if (d.value>breaks.length-1){ 
       return colours[breaks.length] 
      } 

色がまだ返却されていない場合、コードのこのセクションでは、唯一私がなぜわからないものの4550より大きいそれらの値のために、つまり、と呼ばれていますこのコードブロックのif文が必要です。配列breakscoloursは同じ長さです。基本的にはarray[array.length]を返していますが、配列のインデックスがゼロであるため値を返しません。最後に指定した色を使用したい場合は、colours[colours.length-1]を返すことをお勧めします。


編集:あなたは(あなたが表示されます)あなたの最低休憩下記のものと、あなたの最高の上で、それらの色を割り当てる場合も、あなたはブレーク値より1色が必要になります。例:1ブレークスケールには、ブレークの上下に2色あります。ただし、意図的に両方にcolours[0]を適用したことがあります。breaks[0]breaks[1]breaks[0]下の値と値:

  if (d.value<breaks[0]) { 
       return colours[0]; 
      } 
      for (i=0;i<breaks.length+1;i++){ 
       if (d.value>=breaks[i]&&d.value<breaks[i+1]){ 
        return colours[i]; 
       } 
      } 
関連する問題