简体   繁体   English

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

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

Trying to use a scaleTime()for my y axis and populate it with all 12 months.尝试为我的 y 轴使用 scaleTime() 并用所有 12 个月填充它。

Here I set the ranges and domain and then apply the full month name format with %B.在这里,我设置了范围和域,然后使用 %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"));

I expect the y scale to show January at the bottom, December at the top and all month ordered in between.我希望 y 比例在底部显示一月,在顶部显示十二月,并在两者之间订购所有月份。

Instead the first month shown is February, followed by all the months and then December is shown just below the final tick line.相反,显示的第一个月是二月,然后是所有月份,然后十二月显示在最后一个刻度线的正下方。

Below is the full code snippet:下面是完整的代码片段:

 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>

You have a few options here.你有几个选择。 The first, most straight-forward way, is to specify the number of ticks you want - in your case 12.第一种最直接的方法是指定您想要的刻度数 - 在您的情况下为 12。

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

With this approach what you might find that d3 will still fail to render the appropriate number of ticks, which is obviously frustrating.使用这种方法,您可能会发现 d3 仍然无法呈现适当数量的滴答声,这显然令人沮丧。

According to the docs根据文档

The specified count is only a hint;指定的计数只是一个提示; the scale may return more or fewer values depending on the domain.比例尺可能会返回更多或更少的值,具体取决于域。

Another option is to explicitly define the 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"));

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

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