我正在显示基于年和月的温度图。我想在图表底部显示一个图例,以显示每种颜色对应的温度。有人可以帮我理解如何做到这一点以及我做错了什么?
以下是此特定部分的代码:
svg.selectAll("rect")
.data(colors)
.enter()
.append("rect")
.attr("x", (d, i) => {
return 300 + i*legendWidth})
.attr("y", h - 50)
.attr("width", legendWidth)
.attr("height", legendHeight)
.attr("fill", (d, i) => colors[i])
.attr("fill-opacity", "0.5");
这是一个Codepen:https://codepen.io/lieberscott/pen/dmjJWg?editors=0110
Full JS:
document.addEventListener("DOMContentLoaded",function(){
req=new XMLHttpRequest();
req.open("GET","https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/global-temperature.json", true);
req.send();
req.onload=function(){
const dataset=JSON.parse(req.responseText);
const data = dataset.monthlyVariance;
const w = 1000;
const h = 600;
const padding = 92;
const boxWidth = Math.ceil(w / (data.length / 12)); // width / number of years
const boxHeight = Math.floor((h - padding - padding) / 12) + 4; // height / 12
// need +4 above because 1753 months != 2015 months
const months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
const colors = ["#3910ed", "#3479f9", "#2fc0ed", "#36edba", "#e2fff7", "#fff1a5", "#d6bc2c", "#f9a86d", "#c17036", "#f26060", "#561212"];
const legendWidth = 30;
const legendHeight = 20;
const svg = d3.select(".chart")
.append("svg")
.attr("width", w)
.attr("height", h);
const xScale = d3.scaleLinear()
.domain([1753, 2015])
.range([padding, w - padding]);
const yScale = d3.scaleLinear()
.domain([1, 12])
.range([padding, h - padding]);
let tooltip = d3.select("body")
.append("div")
.attr("class", "tooltip");
svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("x", (d, i) => xScale(d.year))
.attr("y", (d, i) => yScale(d.month - 1))
.attr("width", boxWidth)
.attr("height", boxHeight)
.attr("fill", (d) => 8.66 + d.variance < 3 ? colors[0] : 8.66 + d.variance < 4 ? colors[1] : 8.66 + d.variance < 5 ? colors[2] : 8.66 + d.variance < 6 ? colors[3] : 8.66 + d.variance < 7 ? colors[4] : 8.66 + d.variance < 8 ? colors[5] : 8.66 + d.variance < 9 ? colors[6] : 8.66 + d.variance < 10 ? colors[7] : 8.66 + d.variance < 11 ? colors[8] : 8.66 + d.variance < 12 ? colors[9] : colors[10])
.attr("fill-opacity", "0.5")
.on("mousemove", (d) => {
tooltip
.style("left", d3.event.pageX - 50 +"px")
.style("top", d3.event.pageY - 70 + "px")
.style("display", "inline-block")
.html("<span>" + d.year + " — " + months[d.month-1] + "<br/>" + Math.round((8.33 + d.variance)*100)/100 + " ℃<br/>" + d.variance + " ℃</span>")
})
.on("mouseout", (d) => {
tooltip
.style("display", "none");
});
svg.selectAll("rect")
.data(colors)
.enter()
.append("rect")
.attr("x", (d, i) => {
return 300 + i*legendWidth})
.attr("y", h - 50)
.attr("width", legendWidth)
.attr("height", legendHeight)
.attr("fill", (d, i) => colors[i])
.attr("fill-opacity", "0.5");
svg.selectAll("text")
.data(months)
.enter()
.append("text")
.text((month) => month)
.attr("x", padding - 5)
.attr("y", (month, i) => (padding + (i*boxHeight) - boxHeight / 3)) // divided by 3 instead of 2 b/c y attribute aligns by bottom of text and I want it to be centered
.style("text-anchor", "end");
const xAxis = d3.axisBottom(xScale);
// .tickFormat(d3.timeFormat("%Y")); // so it's 2015, not 2,015
svg.append("g")
.attr("transform", "translate(0," + (h - padding) + ")")
.call(xAxis);
svg.append("text") // subhead
.attr("x", w/2)
.attr("y", 20)
.attr("font-size", "25px")
.style("text-anchor", "middle")
.text("1753 - 2015");
svg.append("text") // subhead
.attr("x", w/2)
.attr("y", 35)
.attr("font-size", "12px")
.style("text-anchor", "middle")
.text("Temperatures are in Celsius and reported as anomalies relative to the Jan 1951-Dec 1980 average.");
svg.append("text") // subhead
.attr("x", w/2)
.attr("y", 50)
.attr("font-size", "12px")
.style("text-anchor", "middle")
.text("Estimated Jan 1951-Dec 1980 absolute temperature ℃: 8.66 +/- 0.07.");
};
});
答案 0 :(得分:2)
出现问题的原因是您创建了图例:
svg.selectAll("rect")
.data(colors)
.enter()
.append("rect")
...
第一行选择DOM中已有的矩形,即构成可视化/图表的矩形。
第二行更新此选择的数据。由于选择中的矩形多于数据数组中的颜色,因此无需输入,输入选择为空,因此不会附加任何内容。
由于您没有应用任何更新,并且您只是使用(空)输入选择来追加和设置图例样式,因此可视化中没有任何明显变化。
相反,您可以使用svg.selectAll(null)
(或svg.selectAll()
),这将创建一个空选择,以便为数据数组中的每个项目输入一个项目。这是一个更新的plunkr。