尝试在我的y轴上使用scaleTime()并在全部12个月内填充它。
在这里设置范围和域,然后在%B上应用完整的月份名称格式。
const yScale = d3.scaleTime()
.domain([new Date().setMonth(0),new Date().setMonth(11)])
.range([h-padding, padding]);
const yAxis = d3.axisLeft(yScale)
.tickFormat(d3.timeFormat("%B"));
我希望y刻度显示在底部的1月,顶部的12月,以及介于其间的所有月份。
显示的第一个月是2月,然后是所有月份,然后在最后的刻度线下方显示了12月。
下面是完整的代码段:
document.addEventListener('DOMContentLoaded', async function() {
const res = await d3.json("https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/global-temperature.json");
const BASE_TEMP = parseFloat(res.baseTemperature);
document.getElementById("description").textContent =res.monthlyVariance[0]["year"] + "-" + res.monthlyVariance[res.monthlyVariance.length-1]["year"] + ": Base Temperature: " + BASE_TEMP;
const w = 800;
const h = 500;
const padding = 60;
const barWidth = (w-padding)/res.monthlyVariance.length;
const barHeight = (h-padding)/12;
const xScale = d3.scaleTime()
.domain([new Date().setFullYear(d3.min(res.monthlyVariance, (d,i)=>parseInt(d["year"]))),new Date().setFullYear(d3.max(res.monthlyVariance, (d,i)=>parseInt(d["year"])))])
.range([padding, w - padding]);
const yScale = d3.scaleTime()
.domain([new Date().setMonth(0),new Date().setMonth(11)])
.range([h-padding, padding]);
const xAxis = d3.axisBottom(xScale);
const yAxis = d3.axisLeft(yScale)
.tickFormat(d3.timeFormat("%B"));
const svg = d3.select("#canvas")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.append("g")
.attr("id", "x-axis")
.attr("transform", "translate(0," + (h - padding) + ")")
.call(xAxis);
svg.append("g")
.attr("id", "y-axis")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);
svg.selectAll("rect")
.data(res.monthlyVariance)
.enter()
.append("rect")
.attr("width",barWidth)
.attr("height",barHeight)
.attr("x",(d,i)=>xScale(new Date().setFullYear(d["year"])))
.attr("y", (d,i)=>yScale(new Date().setMonth(parseInt(d["month"])-1)))
.attr("data-year",(d,i)=>d["year"])
.attr("data-month",(d,i)=>d["month"])
.attr("data-temp",(d,i)=>(BASE_TEMP+parseFloat(d["variance"])))
.attr("class", "cell")
.attr("fill", function(d,i){
let variance = parseInt(d["variance"]);
let color = "green";
if (variance<-2) {color="blue"}
else if (variance<-1) {color="lightgreen"}
else if (variance<1) {color="green"}
else if (variance<2) {color="orange"}
else {color="red"}
return color;});
});
#container {
position:absolute;
width:800px;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
text-align:center;
}
#title {
font-size:20px;
}
.cell:hover {
background:lightgrey;
}
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.1/d3.min.js"></script>
<div id="container">
<div id="title">Variation in Monthly Land Temperature</div>
<div id="description">Update this Message from Dataset</div>
<div id="canvas"></div>
</div>
</body>
答案 0 :(得分:1)
您在这里有一些选择。第一种,最直接的方法是指定您想要的刻度数-在您的情况下为12。
const yAxis = d3.axisLeft(yScale)
.ticks(12)
.tickFormat(d3.timeFormat("%B"));
使用这种方法,您可能会发现d3仍然无法渲染适当数量的刻度,这显然令人沮丧。
根据docs
指定的计数只是一个提示;规模可能会增加或减少 值取决于域。
另一种选择是显式定义tick values。
const tickValues = Array(12).fill(1).map((val, index) => new Date().setMonth(index));
const yAxis = d3.axisLeft(yScale)
.tickValues(tickValues)
.tickFormat(d3.timeFormat("%B"));