Javascript D3:为什么';热图颜色图例是否出现?

Javascript D3:为什么';热图颜色图例是否出现?,javascript,d3.js,Javascript,D3.js,情况: <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-temperatu

情况:

<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>

问题:

<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>
我正在尝试用我管理的D3.js创建一个热图图。我现在很难让传奇出现

为什么传说没有出现

图例应如下所示,例如:

代码:

<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>

//汤姆·梅(Tom May)的优秀榜样在我陷入困境时帮助了我:http://bl.ocks.org/tjdecke/5558084
d3.json(“https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/global-temperature.json,函数(错误,json){
如果(错误){
返回控制台。警告(错误);
}
可视化(json);
});
函数(数据){
const baseTemperature=data.baseTemperature;
常数tempData=data.monthlyVariance;
常量边距={
前10名,
右:85,
底数:65,
左:70
}
常量w=1250-margin.left-margin.right;
常数h=500-margin.top-margin.bottom;
const barWidth=Math.ceil(带tempData.length);
常量legendElementWidth=w/12;
常量颜色=[“#5e4fa2”、“#3288bd”、“#66c2a5”、“#abdda4”、“#e6f598”、“#ffffbf”、“#fee08b”、“#fdae61”、“#f46d43”、“#d53e4f”、“#9e0142”];
const bucket=colors.length;
常量月=[“一月”、“二月”、“三月”、“四月”、“五月”、“六月”、“七月”、“八月”、“九月”、“十月”、“十一月”、“十二月”];
const minTime=d3.min(tempData,(d)=>新日期(d.year,1,1,0,0));
const maxTime=d3.max(tempData,(d)=>新日期(d.year,1,1,0,0));
常量xScale=d3.scaleTime()
.domain([minTime,maxTime])
.范围([margin.left,w]);
常量xAxis=d3.axisBottom(xScale).ticks(20);
const svg=d3.选择(“结果”)
.append(“svg”)
.attr(“宽度”,w+边距。左侧+边距。右侧)
.attr(“高度”,h+margin.top+margin.bottom);
常量div=d3。选择(“主体”)
.附加(“div”)
.attr(“类”、“工具提示”)
.样式(“不透明度”,0);
svg.append(“g”)
.attr(“变换”、“平移(0)”+(h+margin.top)+”)
.呼叫(xAxis);
const monthslables=svg.selectAll(“月标签”)
.数据(月)
.输入()
.append(“文本”)
.text((d)=>d)
.attr(“x”,100)
.attr(“y”,(d,i)=>i*h/12+21)
.style(“文本锚定”、“结束”)
.attr(“转换”、“转换(-40、+0+)”)
.style(“字体大小”,10);
const colorScale=d3.scaleQuantile()
.domain([d3.min(tempData,(d)=>d.variance+baseTemperature),d3.max(tempData,(d)=>d.variance+baseTemperature)])
.范围(颜色);
const heatMap=svg.selectAll(“月”)
.数据(tempData,(d)=>d);
const rects=heatMap.enter()
.append(“rect”)
.attr(“x”,(d)=>xScale(新日期(d.year,1,1,0,0)))
.attr(“y”,(d)=>d.month*h/12-margin.bottom+margin.top-1)
.attr(“宽度”,条形宽度+3)
.attr(“高度”,h/12)
.样式(“填充”,颜色[0])
.on(“鼠标悬停”,函数(d){
过渡部()
.持续时间(200)
.样式(“不透明度”,.9);
div.html(d.year+“”+月[d.month-1]+“
”+(d.variance+基准温度).toFixed(3)+“°;C
”+d.variance+“variance”) .style(“左”,“d3.event.pageX)+“px”) .style(“top”,(d3.event.pageY-50)+“px”); }) .on(“mouseout”),函数(d){ 过渡部() .持续时间(500) .样式(“不透明度”,0); }); rects.transition()持续时间(1000) .样式(“填充”,d)=>色标(d.方差+基准温度); svg.append(“文本”) .attr(“转换”, “翻译(“+(w/2)+”,“+ (h+margin.top+45+“”) .style(“文本锚定”、“中间”) .文本(“年”); svg.append(“文本”) .attr(“变换”、“旋转(-90)”) .attr(“y”,-5) .attr(“x”,0-(h/2)) .attr(“dy”、“1em”) .style(“文本锚定”、“中间”) .文本(“月份”); const legend=svg.selectAll(“图例”) .data([0].concat(colorScale.quantiles()),(d)=>d); const legendEntries=legend.enter().append(“g”) .attr(“类别”、“图例”); legendEntries.append(“rect”) .attr(“x”,(d,i)=>(w*0.7)+legendElementWidth/4*i) .attr(“y”,h+40) .attr(“宽度”,legendElementWidth) .attr(“高度”,20) .style(“填充”(d,i)=>颜色[i]); legendEntries.append(“文本”) .数据(临时数据) .text((d)=>”≥ " + 数学四舍五入(d.方差+基准温度)) .attr(“x”,(d,i)=>(w*0.7)+legendElementWidth/4*i) .attr(“y”,h+75); }
此代码导致您出现问题:

   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);
请注意,您的enter选择仅用于附加“g”元素。您还需要使用enter选择附加矩形和文本。请将代码与以下内容进行对比:

   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”中


这不是您问题的一部分,但您可能希望检查您传递给图例的数据。

为什么要进行否决投票?如果必要,我愿意修改我的问题,但请解释。我没有否决您的投票,但您的标题可以更具体。控制台中是否有错误?a