Правильно отображать все месяцы по оси Y графика d3 - PullRequest
0 голосов
/ 12 февраля 2019

Попытка использовать scaleTime () для моей оси y и заполнить его всеми 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>

1 Ответ

0 голосов
/ 12 февраля 2019

У вас есть несколько вариантов здесь.Первый, самый простой способ, это указать желаемое количество тиков - в вашем случае 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"));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...