2017-04-27 24 views
1

SITUATION:D3:ヒートマップの色の凡例が表示されないのはなぜですか?

enter image description here

QUESTION:

私は私が管理しD3.jsとヒートマップグラフを作成しようとしています。私は今、伝説を現われるのに問題があります。

凡例が表示されないのはなぜですか?

伝説がここに例えばのように表示されます。

https://codepen.io/freeCodeCamp/full/aNLYPp

CODE:

<script type="text/javascript"> 

    // Excellent example from Tom May helped me when I got stuck: http://bl.ocks.org/tjdecke/5558084 
    d3.json("https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/global-temperature.json", function(error, json) { 
     if (error) { 
      return console.warn(error); 
     } 
     visualizeThe(json); 
    }); 

    function visualizeThe(data) { 

     const baseTemperature = data.baseTemperature; 
     const tempData = data.monthlyVariance; 

     const margin = { 
      top: 10, 
      right: 85, 
      bottom: 65, 
      left: 70 
     } 

     const w = 1250 - margin.left - margin.right; 
     const h = 500 - margin.top - margin.bottom; 
     const barWidth = Math.ceil(w/tempData.length); 
     const legendElementWidth = w/12; 


     const colors = ["#5e4fa2", "#3288bd", "#66c2a5", "#abdda4", "#e6f598", "#ffffbf", "#fee08b", "#fdae61", "#f46d43", "#d53e4f", "#9e0142"]; 
     const buckets = colors.length; 
     const months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; 

     const minTime = d3.min(tempData, (d) => new Date(d.year,1,1,0,0)); 
     const maxTime = d3.max(tempData, (d) => new Date(d.year,1,1,0,0)); 

     const xScale = d3.scaleTime() 
      .domain([minTime, maxTime]) 
      .range([margin.left, w]); 

     const xAxis = d3.axisBottom(xScale).ticks(20); 

     const svg = d3.select("#results") 
      .append("svg") 
      .attr("width", w + margin.left + margin.right) 
      .attr("height", h + margin.top + margin.bottom); 

     const div = d3.select("body") 
      .append("div") 
      .attr("class", "tooltip")    
      .style("opacity", 0); 

     svg.append("g") 
      .attr("transform", "translate(0," + (h+margin.top) + ")") 
      .call(xAxis); 

     const monthsLabels = svg.selectAll("monthLabel") 
      .data(months) 
      .enter() 
      .append("text") 
      .text((d) => d) 
      .attr("x", 100) 
      .attr("y", (d,i) => i * h/12 + 21) 
      .style("text-anchor", "end") 
      .attr("transform", "translate(-40," +0+ ")") 
      .style("font-size", 10); 

     const colorScale = d3.scaleQuantile() 
      .domain([d3.min(tempData, (d) => d.variance + baseTemperature), d3.max(tempData, (d) => d.variance + baseTemperature)]) 
      .range(colors); 

     const heatMap = svg.selectAll("month") 
      .data(tempData, (d) => d); 

     const rects = heatMap.enter() 
      .append("rect") 
      .attr("x", (d) => xScale(new Date(d.year,1,1,0,0))) 
      .attr("y", (d) => d.month * h/12 - margin.bottom + margin.top -1) 
      .attr("width", barWidth + 3) 
      .attr("height", h/12) 
      .style("fill", colors[0]) 
      .on("mouseover", function(d) {   
      div.transition()   
       .duration(200)  
       .style("opacity", .9);  
      div .html(d.year +" "+ months[d.month-1]+"<br>"+(d.variance + baseTemperature).toFixed(3)+" &deg;C <br>"+d.variance+" Variance") 
       .style("left", (d3.event.pageX) + "px")  
       .style("top", (d3.event.pageY - 50) + "px");  
      })     
      .on("mouseout", function(d) {  
      div.transition()   
       .duration(500)  
       .style("opacity", 0); 
      }); 

     rects.transition().duration(1000) 
      .style("fill", (d) => colorScale(d.variance + baseTemperature)); 

      svg.append("text")    
       .attr("transform", 
        "translate(" + (w/2) + " ," + 
        (h+ margin.top + 45) + ")") 
       .style("text-anchor", "middle") 
       .text("Years"); 

      svg.append("text") 
       .attr("transform", "rotate(-90)") 
       .attr("y", -5) 
       .attr("x",0 - (h/2)) 
       .attr("dy", "1em") 
       .style("text-anchor", "middle") 
       .text("Months"); 

     const legend = svg.selectAll("legend") 
      .data([0].concat(colorScale.quantiles()), (d) => d); 

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

      legendEntries.append("rect") 
      .attr("x", (d, i) => (w*0.7)+ legendElementWidth/4 * i) 
      .attr("y", h + 40) 
      .attr("width", legendElementWidth) 
      .attr("height", 20) 
      .style("fill", (d, i) => colors[i]); 

      legendEntries.append("text") 
      .data(tempData) 
      .text((d) => "≥ " + Math.round(d.variance+baseTemperature)) 
      .attr("x", (d, i) =>(w*0.7)+ legendElementWidth/4 * i) 
      .attr("y", h + 75); 
    } 

</script> 
+0

なぜdownvoteですか?私は必要に応じて私の質問を修正したいと思っていますが、説明してください。 – Coder1000

+0

私はあなたにdownvoteをしませんでしたが、あなたのタイトルはもっと具体的である可能性があります。 –

+0

コンソールにエラーがありますか?また、これを見て:http://stackoverflow.com/questions/41439050/unable-to-display-legend-for-a-quantile-scale-in-d3/41445879#41445879 – mkaran

答えて

2

このコードはあなたに引き起こしている問題:あなたの入力した選択が使用されている

const legend = svg.selectAll("legend") 
     .data(tempData.concat(colorScale.quantiles()), (d) => d["month"]); 

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

     legend.append("rect") 
     .attr("x", (d,i) => legendElementWidth * i) 
     .attr("y", h) 
     .attr("width", legendElementWidth) 
     .attr("height", 5) 
     .style("fill", (d, i) => colors[i]); 

     legend.append("text") 
     .attr("class", "mono") 
     .text((d) => "≥ " + Math.round(d.variance+baseTemperature)) 
     .attr("x", (d, i) =>legendElementWidth * i) 
     .attr("y", h + 4); 

注意'g'要素を追加する場合にのみ使用します。入力選択を使用して長方形とテキストを追加する必要があります。コードを次のように比較してください。

const legend = svg.selectAll("legend") 
     .data(tempData.concat(colorScale.quantiles()), (d) => d["month"]); 

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

     legendEntries.append("rect") 
     .attr("x", (d,i) => legendElementWidth * i) 
     .attr("y", h) 
     .attr("width", legendElementWidth) 
     .attr("height", 5) 
     .style("fill", (d, i) => colors[i]); 

     legendEntries.append("text") 
     .attr("class", "mono") 
     .text((d) => "≥ " + Math.round(d.variance+baseTemperature)) 
     .attr("x", (d, i) =>legendElementWidth * i) 
     .attr("y", h + 4); 

Enterキーを押すと、DOMに追加する必要のある要素が返されます。ここでは、追加する必要のある要素ごとに、そのデータと共に 'g'を追加します。次に、入力した 'g'に項目を追加します。

質問の一部ではありませんが、凡例に渡すデータを調べることができます。

関連する問題