繁体   English   中英

在 d3 图表的 y 轴上正确显示所有月份

[英]Correctly displaying all months in y-axis of d3 graph

尝试为我的 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 比例在底部显示一月,在顶部显示十二月,并在两者之间订购所有月份。

相反,显示的第一个月是二月,然后是所有月份,然后十二月显示在最后一个刻度线的正下方。

下面是完整的代码片段:

 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>

你有几个选择。 第一种最直接的方法是指定您想要的刻度数 - 在您的情况下为 12。

const yAxis = d3.axisLeft(yScale)
  .ticks(12)
  .tickFormat(d3.timeFormat("%B"));

使用这种方法,您可能会发现 d3 仍然无法呈现适当数量的滴答声,这显然令人沮丧。

根据文档

指定的计数只是一个提示; 比例尺可能会返回更多或更少的值,具体取决于域。

另一种选择是明确定义刻度值

const tickValues = Array(12).fill(1).map((val, index) => new Date().setMonth(index));
const yAxis = d3.axisLeft(yScale)
  .tickValues(tickValues)
  .tickFormat(d3.timeFormat("%B"));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM