2016-12-29 74 views
2

我想将图例添加到日历热图中。但是,目前该图例仅包含两个元素> 0%> NaN%。我尝试了不同的方式来设置图例,但仍不能解决问题。如何在日历热图中添加图例

如何定义值应取自colorScale?为什么我的值为> 0%> NaN%而不是colorScale中定义的值?

<!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.threshold() 
      .domain([5, 10, 15]) 
      .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), 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

回答

0

它只是在你的代码中的小的失误。你提供给你的传奇的数据是包含零和你colorScale功能的阵列:

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

你可能想是这样的:

var colorScaleDomain = [5, 10, 15] 
var colorScale = d3.scale.threshold() 
    .domain(colorScaleDomain) 
    .range(colors); 
(...) 

var legend = svg.selectAll(".legend") 
    .data([0].concat(colorScaleDomain));